IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]go学习笔记

    chgaowei发表于 2014-03-15 20:50:33
    love 0
    go学习笔记

    初始go

    异常处理的defer是个不错的特性,虽然说有人反驳说其中的java代码不够合理,但是这种方式确实对c是一个巨大的进步。
    工程编译根据方便,没有Makefile文件,只要一个go命令即可。但是必须要设置GOPATH路径,这一步能省掉就更好了。


    顺序编程

    变量:
    支持:int,字符串,数组,数组切片,结构体,指针,字典,函数指针。
    iota:在每次const是初始化为0,每出现一次会自增1。

    全局变量不支持类型推导——:=

    go 的取反是^而不是~

    float64相当于c中的double。

    浮点数的比较不可以使用==,因为有精度问题。

    字符串在go中是一种基本类型:

    go中有两种字符类型:byte,其实就是uint8,代表utf-8的单个字节,另一个是rune,代表单个Unicode字符。

    go的api多数假设字符串为utf-8编码。

    go中的数组时值类型,作为函数参数是进行了一次的拷贝操作。函数无法修改入参的值。

    var v [3][5]int = [3][5] int{{1,2},{3,4},{5,6}}//数组初始化

    数组长度定义后无法修改,数组时值类型,每次传递产生一个副本。


    数组切片:
    切片可以动态扩展空间(是不是无限制扩展?),随意传递而不会重复复制。

    s := v[:]
    s := v[:5]
    s := v[5:]
    s := v[1:5]
    s := make([]int, 5)//5个元素
    s := make([]int, 5, 10)//5个元素,存储能力为10
    s := []int{1,2,3,4,5,6}


    使用cap可以获得切片的存储能力,len可以获得切片的长度。
    基于数组创建切片存储能力就是数组的大小。

    append函数可以为切片添加元素。
    s = append(s, 1 , 2, 3, 4)//为s添加四个元素。第二个参数是可变参数。
    vslice = append(vslice, vslice...)//为一个切片追加另外一个切片。省略号表示取切片的每个元素。

    基于数组切片创建切片:范围可以超过原有的len,但是不可以超过cap。否则会异常。
    newvs := vslice[:50]
    fmt.Println( cap(newvs), len (newvs))

    更改数组的切片的值,会更改数组。切片类似于数组指针。

    !数组切片在append后,便是脱离了原有的数组,形成了一块新的存储,更改切片值,不会再更改原有的数组内容。这是一个容易引起错误的地方。

    可以使用copy函数对切片进行复制:将一个切片的内容复制到另外一个切片中。copy从第二个参数中拷贝入第一个参数中。拷贝的个数时两个切片最小元素个数。不会将剩余元素设置为空。

    MAP:
    定义:
    var mymap map[ int]string
    变量名 key类型 value类型

    var mymap map[ int]string = map[int]string{1: "1", 2:"2" , 3:"3"}//定义并初始化

    复制类似Python。可以用make创建,并制定存储能力。

    删除用delete。


    流程控制:

    if后没有(),可以加变量定义(if i := 5; i > 2 && i <= 7{)。else必须与上一个}在一行。

    switch:
    条件可以是字符串等,不限定为常量或整数。
    没有break。不会自动执行下一个,需要手动添加fallthrough。没有条件是,逻辑相当于 if else if ...

    循环:
    无限循环的写法。
    for {
    }

    循环条件中支持多重赋值。break可以控制停止那个循环。通过标签来实现,与goto类似。

    函数:
    小写字母开头的包在本包可见,大写字母开头的包在外部可见。
    func(arg ...int)//传递int类型的不定参数。
    func(arg ...interface{})//传递不定类型的不定参数。
    多返回值:定义时初始化,后面可以使用返回值变量,如果只有return,则自动返回之前的返回值变量
    匿名函数:
    由一个不带函数名的函数声明和函数体构成,可以直接赋值或执行。
    闭包的用法:

    func fun_test(i int)(func(a, b int)(ret bool , c int)){
    ret, e := fun1(1, 2)
    fmt.Println( "fun1 return is :", ret, e )
    fun2 := func (a, b int) (ret bool, c int){
    return a < b, i
    }
    return fun2
    }
    闭包使用匿名函数来实现的。

    defer,panic,recover关键字处理异常
    defer关键字无论是否发生异常都会调用。
    panic,recover不是特别理解,留待后面用的时候在看。

    面向对象编程

    类型系统:
    go可以为任意类型定义方法:包括内置,当不包括指针。

    type integer int:定义一个新的类型,以int为基础。

    为类型定义新的方法:
    func (a integer)Less(b int)bool{ //func后面的 a integer表示类型。如果方法中需要修改,则可以用a *integer
    return a < b
    }

    go语言一般情况是值语义,只有数组切片,map,chanel,接口是引用语义。


    go提供接口查询功能。检查一个对象是否实现某一接口。也可以检查对象是否是某一类型。

    接口是可以自由组合的?如何调用。

    并发编程

    go关键字
    可以实现并发。
    channel:gocoroutine之前的通信通道。是类型安全的,只能够传递一种类型。

    channel的读写操作对携程来说都是阻塞的。需要再数据被写入或读取后才向下执行。类似于阻塞时的套接字。
    异步处理多个套接字或者channel,可以使用select。

    channel可以设置缓存,在缓冲被填满前都不好被阻塞。

    可以是range从带缓冲的通道中读多个内容。

    可以利用select自己增加一个通道的超时机制。

    目前需要多核运行需要设置环境变量:runtime.GOMAXPROCS(4)。

    出让时间片,暂停协程运行函数:Gosched。

    go提供两种锁。读写锁和单一锁。

    sync的once可以保证一个函数在所有的协程中(也就是全局)只被调用一次。防止多个协程对一个借口的调用。



    网络编程


    net的Dial函数对套接字,连接等操作进行了封装,可以选择协议,并且发起连接。除此之外还有很多分支的Dial系列接口,可以完成更丰富的操作。

    go在底层封装了http的客户端和服务前端的库。

    go支持rpc。net\rpc包能够支持远程调用。

    gob是一个可以对数据结构进行序列化的工具。rpc内部就是使用gob。

    go的net/rpc/json提供JSON-RPC。

    go的encoding/json标准库,开发者可以轻松的使用go程序生成和解析json。

    go编写json比较方便,可以自动将结构体的变量名编码为key,将值转化为value。(我想在c中实现的想法)

    解码未知结构可以使用map。



    工程管理


    go提供丰富的命令行,可以完成很多工作:代码检查,格式,等。

    高级话题
    reflect提供放射













沪ICP备19023445号-2号
友情链接