go语言中make和new的区别

  • make用于初始化内置的数据结构,如slice,map,channel
  • new的作用是根据传入的类型分配一片内存空间并返回指向这片内存空间的指针
    1
    2
    3
    slice := make([]int, 0, 100)
    hash := make(map[int]bool, 10)
    ch := make(chan int, 5)
    1. slice是一个包含data,cap和len的结构体reflect.SliceHeader
    2. hash是一个指向runtime.hmap结构体的指针
    3. ch是一个指向runtime.hchan结构体的指针
1
2
3
4
i := new(int)

var v int
i := &v

上述代码片段两种初始化方法是等价的,它们都会创建一个指向int零值的指针

make

在编译期间的类型检查阶段,go语言会将代表make关键字的OMAKE节点根据参数类型的不同转换成了OMAKESLICEOMAKEMAPOMAKECHAN三种不同类型的节点,这些节点会调用不同的运行时函数来初始化相应的数据结构。

new

编译器会在中间代码生成阶段通过以下两个函数处理该关键字:

  1. cmd/compile/internal/gc.callnew会将关键字转换成ONEWOBJ类型的节点
  2. cmd/complie/internal/gc.state.expr会根据申请空间的大小分两种情况处理
    1. 如果申请的空间为0,就会返回一个表示空指针的zerobase变量
    2. 在遇到其他情况时会将关键字转换成runtime.newobject函数

      小结

      简单总结一下go语言中makenew关键字的实现原理,make关键字的作用是创建切片、哈希表和Channel等内置的数据结构,而new的作用是为类型申请一片内存空间,并返回指向这片内存的指针。