零值
要了解make和new首先要了解golang中关于零值的定义:当一个变量或者新值被创建时, 如果没有为其明确指定初始值,go语言会自动初始化其值为此类型对应的零值。各类型的零值如下:
- bool : false
- integer : 0
- float : 0.0
- string : “”
- pointer, function, interface, slice, channel, map: nil
对于复合类型,如数组,结构体,go语言会自动递归地将每一个元素初始化为其类型对应的零值。
new
new的结果是一个指针。在new(T)时会为对象T分配新的内存,将其置零,并返回它的地址(一个类型为*T的值)
如果用C语言来描述golang中new的过程,可以解释为
1 | T *t = (T*)malloc(sizeof(T)) |
make
一般来说我们只用make来创建slice, map 和 channel。 并且返回一个初始化的(而不是置零),类型为T的值(而不是*T)
new和make的对比
从返回值上来说,new返回的是*T,是一个指针;make的返回值直接为T类型。
其次对于slice,map和channel类型的变量,我们一般都用make来创建,很少用new来进行创建。
用一段代码来说明make和new的区别:
1 | var p = new([]int) |
从上面的代码中就可以看出,new只是对slice分配了内存并将其置为零值(slice的零值为nil),所以 *p == nil 的判断为true; 而make则是在分配内存之后,对slice进行了初始化,不再为零值(nil)而是一个len=0的slice。