雁过留声

a tiger in me sniffs roses

0%

go语言学习笔记

  • if 可以有多个;隔开的语句,if xxx; yyy {…}。 golang语句分隔符其实是;但是可以省略
  • golang 中函数名头大小写决定了函数在包外的可见性!
  • a := value 简短变量声明只能用 在函数内, 注意是 声明
  • go 中指针是不能改变的
  • 编译器自动选择在栈上还是堆上分配空间,但是不由var还是new方式决定!
  • 注意go 中 := 和 多重赋值, 和作用域的坑
  • 包导入:. “xx”, _ “xx”, f “xx”
  • 在循环中调用函数或者goroutine方法,一定要采用显示的变量调用,不要再闭包函数里面调用循环的参数.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for i:=0; i<limit; i++ {
    go func() { DoSomething(i) }() //错误的做法
    go func(i int){ DoSomething(i) }(i)//正确的做法
    }

    //go run -race
    var msg = "hello"
    go func() {
    fmt.Println(msg)
    }
    msg = "bye"
    //bye
  • var f float64 = 212
    fmt.Println((5 / 9) * (f - 32)) //0 !!!
    fmt.Println((f - 32) * 5 / 9) //100
    fmt.Println((f - 32) * (5 / 9)) //0 !!!
    常量是在编译时确定的!! go 中常量还有无类型字面量,精度更高。
    在声明中,无类型会转换成相应类型
  • slice 包含了一个指向数组的指针,但并非严格引用类型,append操作可能返回不同的底层
  • 而数组是值类型,a = […]{1,2,3}; b := a; a[1] = 42; a,b 不等
  • map == nil 时存入会异常. 允许对值为 nil 的 slice 添加元素,但对值为 nil 的 map 添加元素则会造成运行时 panic
  • 在go语言中所有函数参数是值拷贝传入
  • switch 语句中的 case 代码块会默认带上 break,但可以使用 fallthrough 来强制执行下一个 case 代码块
  • 组合是go中面向对象的核心
  • go中函数栈是可变栈,递归深度没有限制?
  • print, println 不像fmt.print那样可以打印结构体等复杂类型,并没有格式化功能?
  • 闭包中引用的局部变量是地址,而不是某一时刻的值。注意这个陷阱,这在其它语言中也存在
  • defer 语句是在函数返回后执行!所以可以在函数内观察到返回值。参数是在defer声明时候确定
  • 可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反
  • 即使发生panic, defer语句也会执行!
  • recover 只在defer函数中有用
  • 语言中最小的封装单元是package, 可见性是以包为单位的
  • 接口有个坑: 包含nil值的接口不是一个nil接口一个接口中包含一个动态类型(一个具体的类型)和一个动态值两部分组成,接口可以和nil比较,这个nil表示一个空接口(不包含任何值的接口)。但是包含nil的接口不是空接口: var i1 *bytes.Buffer 和 var i2 io.Writer 都是nil但是不等
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
       println("----------------------------------")
    var i1 io.Writer
    println(i1)
    println(i1 == nil)

    var i2 *bytes.Buffer
    println(i2)
    println(i2 == nil)

    i1 = i2
    println(i1)
    //注意这里是false
    println(i1 == nil)
    ----------------------------------
    (0x0,0x0)
    true
    0x0
    true
    (0x53c260,0x0)
    false
  • 接口赋值中,如果使用值,则所有实现的reciever都应是值类型,如果是指针,则没有这个限制,可以是值或者指针。
    var a writer = ConcreteWriter{} vs var a *writer = &ConcreteWriter{}
  • 函数中可以安全的返回局部变量的地址。
  • ch <-chan int: readonly channel, 只能读出; ch chan<- int: sendonly channel,只能写入