make 和 new
make 的作用是初始化内置的数据结构,也就是切片、哈希表和 channel
new 的作用是根据传入的类型分配一块内存空间,并返回指向这块内存空间的指针
一、make
在编译期间的类型检查阶段,Go 语言会将代表 make
关键字的 OMAKE
节点根据参数类型的不同转换成了 OMAKESLICE
、OMAKEMAP
和 OMAKECHAN
三种不同类型的节点,这些节点会调用不同的运行时函数来初始化相应的数据结构。
二、new
编译器会在中间代码生成阶段通过以下两个关键字处理 new 关键字
cmd/compile/internal/gc.callnew
会将关键字转换成ONEWOBJ
类型的节点2;cmd/compile/internal/gc.state.expr
会根据申请空间的大小分两种情况处理:- 如果申请的空间为 0,就会返回一个表示空指针的
zerobase
变量; - 在遇到其他情况时会将关键字转换成
runtime.newobject
函数
- 如果申请的空间为 0,就会返回一个表示空指针的
无论是直接使用 new
,还是使用 var
初始化变量,它们在编译器看来都是 ONEW
和 ODCL
节点。如果变量会逃逸到堆上,这些节点在这一阶段都会被 cmd/compile/internal/gc.walkstmt
转换成通过 runtime.newobject
函数并在堆上申请内存。
不过这也不是绝对的,如果通过 var
或者 new
创建的变量不需要在当前作用域外生存,例如不用作为返回值返回给调用方,那么就不需要初始化在堆上。