go语言基础概要

来源:互联网 发布:java截取字符串前两位 编辑:程序博客网 时间:2024/06/05 18:52

1 go语言特性

    自动垃圾回收,丰富的内置类型,函数多返回值,匿名函数与闭包,类型与非侵入式接口,并发编程(goroutine),反射机制。

2 基本语法

2.1 变量

2.1.1 变量声名方式

1. var v1 int or var v1 int = 3(声明并赋值)2. var v2 = 3 (自动确定类型)3. v3 := 3

2.1.2 其它

多重赋值:i, j = j, i (交换值)支持匿名变量(_)

2.2 常量

常量定义:const Pi float64 = 3.14159const(    size int = 3    eof = -1)const与itoa用法,一般可用于枚举型

2.3 数据类型

2.3.1 基本类型

1. 布尔类型:bool(只能接受true和false,不能接受其它类型赋值)2. 整型:int8, byte(uint8),int16,uint等3. 浮点类型:float32, float644. 复数类型:complex64, complex128(c := 3 + 3i)5. 字符串:string (s1+s2, len(s), s[i], 两种遍历方式)6. 字符:byte(utf-8字符),rune(unicode字符)7. 错误类型:error

2.3.2 复合类型

1. 指针(类似c语言)2. 数组(元素数量固定)array := [3]int{1,2,3}3. 切片(动态数组)      slice := []int{1,2,3}    slice := make([]int, 3) or make([]int, 3, 5) or 基于数组/切片创建    cap(),len(),copy()和append()函数4. 字典——map     map := map[keyType] valueType {key: value}    map := make(map[keyType] valueType, 3)    delete()和find()函数5. 通道——chan    gorontinue通信

2.4 流程控制

2.4.1 条件语句(if)

1. 条件语句不需要()2. if之后,条件语句之前可以添加初始化语句,用;间隔3. return语句不能包含在if...else...中if v := 3 ; v >=3 {  //左花括号必须与if在同一行    ...    return r   // No}

2.4.2 选择语句(switch)

1. 条件表达式不限定为常量或者整数2. 不需要break来退出一个case3. 只有在case中添加了fallthrouth关键字,才会继续执行下一个case4. swicth后面可以没有条件表达式,相当于if...else...逻辑

2.4.3 循环语句(for)

1. 不需要()2. 不支持使用,来实现多变量初始化,可以使用平行赋值语句3. 支持break, continue

2.4.4 跳转语句(goto)

谨用

2.5 函数

2.5.1 函数定义

func name(arg1, arg2) (ret1, ret2){    ...}

2.5.2 特性

1. 支持多返回值2. 不定参数    func name(args ...int ) 参数个数不定,类型为int    fun name(args ...interface{} ) 参数个数不定,类型不定    调用方式:name(args...)3. 匿名函数    f := func(arg1, arg2) (ret1, ret2)4. 闭包

2.6 错误处理

2.6.1 error接口

接口定义如下:type error interface{    Error() string}凡是实现了Error() string方法的类都属于error类型

2.6.1 defer

函数返回之前执行,一般用于释放资源等操作,当一个函数有多个defer时,调用顺序为先进后出,同时支持匿名defer,定义如下:defer func(){    ...}

2.6.1 panic()和recover()

panic函数

用于报告错误,即在一个函数中执行panic()时,正常的执行流程将终止,但是defer相应函数依然执行,另外panic()会向上层执行panic()

recover函数

用于处理错误,一般用于defer中

3 面向对象

3.1 值与引用

go语言可以算都是基于值的传递,尤其对于数组,在c语言里是传地址,而在go中是传值(注意切片,map,channel,interface的方式,实际也可以看成是传值)

3.2 结构体

3.2.1 定义与初始化

go中的结构体相当于其它语言中的class定义 :type Rect struct{    x, y int    width, height float}初始化:r1 = new(Rect)r2 = Rect{1,1,1,1}r3 = Rect{width: 1, height:1}

3.2.2 继承

go采用组合的方法实现继承例子如下:type Base struct {    Name string}func (base *Base) Foo() {...}func (base *Base) Bar() {...}type Foo struct {    Base  or *Base   (注意区别)    ...}func (foo *Foo) Bar() {     foo.Base.Bar()    ...}上面首先定义基类Base,并且定义Foo()和Bar()两个方法;然后定义Foo(组合继承Base),而且重写了Bar方法.foo.Foo()就会调用Base的Foo()方法注意:命名冲突时,外层覆盖里层的

3.2.3 包可见性

首字母大写则表示对其它包可见

3.3 接口

3.3.1 非侵入式接口

一个类只要实现了某个接口的所有函数,就等于实现了这个接口;终于再也不用画类的继承树图了

3.3.2 接口赋值

1. 对象赋值给接口(两种方式:直接赋值与取地址赋值)2. 接口赋值给接口    两个接口如果方法相同,那么这两个接口实际上没有区别;另外当把接口A赋值给接口B时,B接口    的方法应该是A接口方法的子集

3.3.2 接口查询

_, ok = interface1.(interface2)  interface1所指向的对象是否实现interface2接口的方法特例 interface1.(Type) interface1所指向的对象是否属于Type类型另外 interface1.(type) 获取interface1所指向的对象的类型(用在switch语句中)   

3.3.3 任意类型

var v1 interface{} = 1var v1 interface{} = "string"

4 并发编程

4.1 并发模型

1. 多进程2. 多纯种3. 基于回调的异步非阻塞IO4. 协程

4.2 goroutine

goroutine是Go语言的轻量级线程,由Go的runtime管理. 使用方法: go functionName()

4.3 并发通信

共享数据和消息机制是两种常见的并发通信模型;Go语言采用消息机制的通信模型,称为channel."不要通过共享内存来通信,而应该通过通信来共享内存"

4.4 channel

4.4.1 基本语法

channel是类型相关的,定义方式如下:var channelName chan Typevar ch chan float32 var m map[string] chan boolmake(chan int)单向channel:var ch1 chan<- float32   写var ch2 <- chan float32   读var ch3 := chan<- float(ch)var ch4 := <-chan float(ch)存取channel(channel为空时,读取数据操作会阻塞;channel满时,存储数据操作会阻塞):ch <- valuevalue := <-ch关闭channel:close(ch)

4.4.2 缓存

channel支持缓冲机制, ch = make(ch int, 1024)for i := range ch {    ...}

4.4.3 超时机制

采用select实现超时机制:timeout := make(chan bool, 1)go func(){    time.Sleep(le9)    timeout <- true}()select {    case <- ch :    case <- timeout:}

4.5 多核并行化

如若编译器版本不支持多核并行,则可以通过设置环境变量GOMAXPROCS的值:runtie.GOMAXPROCS(num)

4.5 同步

go语言也支持同步锁,包括sync.Mutex和sync.RWMutext

4.5 全局惟一性操作

sync.Once可以保证某个方法全局只执行一次,例如:var once sync.Onceonce.Do(func)  表示func函数全局只会执行一次

5 网络编程

5.1 socket编程

5.1.1 建立连接

TCP: conn, err = net.Dial("tcp","xxx.xxx.xxx.xxx:xxxx")UDP: conn, err = net.Dial("udp","xxx.xxx.xxx.xxx:xxxx")ICMP: conn, err = net.Dial("ip4:icmp","xxx.xxx.xxx.xxx:xxxx")

5.1.2 读写

conn.Write()   conn.Read()

5.1.3 Dial()

Dial()函数其实是对DialTCP(),DialUDP(),DialIP()和DialUnix()的封装;所以在代码中可以直接使用这些函数

5.2 http编程

5.2.1 Client

Client常用函数(http.Get(),http.Post()等)

func (c *Client) Get(url string) (r *Response, err error)func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err error)func (c *Client) PostForm(url string, data url.Values) (r *Response, err error)func (c *Client) Head(url string) (r *Response, err error)func (c *Client) Do(req *Request) (r *Response, err error)

高级封装

前面介绍的http.Get()实际上是http.DefaultClient.Get(),从而也说明Client是可以自定义的,Client定义如下:type Client type{    //Transport用于确定http请求机制(是否长链接,ssl,连接数等)    Transport RoundTripper    //重定向之前调用该函数    CheckRedirect fuc(req *Request, via []*Request) error    //cookie信息    Jar CookieJar}用户可以自定义Transport,CheckRedirect,Jar;从而根据需要实现自定义Client.

5.3 RPC

5.3.1 相关概念

标准库提供了net/rp包实现了RPC协议的相差细节. 在RPC服务端,可将一个对象注册为可访问的服务,之后该对象的公开方法就能够以远程的方式提供访问。而且一个RPC服务端可以注册多个不同类型的对象,但是不允许注册同一类型的多个对象.对象中的方法需要满足以下要求才可以被远程访问:1. 对象方法必需可供外部调用(首字母大写)2. 必须有两个参数,第二个必须是指针3. 方法必须返回error类型的值如 func (t *T) MethodName(arg T1, reply *T2) error 

5.3.2 例子

服务端

obj := new(Obj)rpc.Register(obj)rpc.HandleHTTP()l, e := net.Listen("tcp", ":3333")if e! = nil {    log.Fatal("listen error: ", e)}go http.Serve(l, nil)

客户端

client, err = rpc.DialHTTP("tcp", address+":3333")同步:err = client.Call()异步:asyCall := client.Go()replyCall := <-asyCall.Done

5.4 JSON解析

5.4.1 编码

json.Marshal()func Marshal(v interface{}) ([]byte, error)

5.4.2 解码

json.Unmarshal()func Unmarshal(data []bite, v interface{}) error注意:已知数据结构的解码与未知数据结构的解码

5.4.3 JSON流式读写

func NewDecoder(r io.Reader) *Decoderfunc NewEncoder(w io.Writer) *Encoder

时间: 2016/01/28

0 0
原创粉丝点击