读Go官方文档笔记

知识小点

常量

创建整数常量时,不管多长的数字,精度都不会丢失,因为它是“常量”

基础类型

基础类型包括:数字类型、布尔类型、字符类型。

比较

在go中必须是两个类型相同的值才可以比较,接口则需要也实现了相应的接口才可比较。

如果其中一个是常量,则需要和常量能兼容的类型才可以比较。

如果都不满足,则需要转换成相同类型才可以比较。

值类型与引用类型

int、float、bool、string这些基本类型属于值类型,数组结构也属于值类型,这些的变量直接指向内存中的值。

指针、切片、map、chan为引用类型,引用类型储存的是值所在的内存地址,或者内存地址中第一个值所在的位置,内存地址又称为指针。

当引用类型被使用=进行复制时,是对内存地址的复制,并非值的复制,当修改其中一个的值时,也会改变另一个变量的值。

不管是值类型还是引用类型,都可以使用&进行取地址。

内存逃逸分析

栈空间:系统自己申请和释放
堆空间:程序员自己申请和释放,在go中由GC搞定

go build -gcflags=-m 可以检查代码的编译优化情况,包括逃逸情况和函数是否内联
  1. 指针逃逸
    指针是指向堆中的指针,此时会发生逃逸到堆上
  2. 栈空间不足
    局部变量下,编译器认为,分配给变量的内存占用大,则分配到堆中
  3. 可变参数
    编译期间,不确定参数,或不确定参数数量,则会发生逃逸,分配到堆上,如...interface{}
  4. 闭包引用对象

    type Func func(x int) int
    func A() Func {
     var i int = 1
     return func(x int) int {
         i++
         return x+i
     }
    }
  5. 外部引用局部变量指针
    外部调用函数时,函数返回内部局部变量的指针,此时会发生内存逃逸
    因为在后续变量i也会用到,所以分配到堆上