理解并记录golang 内置函数new()和make()的区别
new
// The new built-in function allocates memory. The first argument is a type, // not a value, and the value returned is a pointer to a newly // allocated zero value of that type. func new(Type) *Type
即内建函数 new 用来分配内存,它的第一个参数是一个类型,不是一个值,它的返回值是一个指 向新分配类型零值的指针
make
//The make built-in function allocates and initializes an object //of type slice, map, or chan (only). Like new, the first argument is // a type, not a value. Unlike new, make's return type is the same as // the type of its argument, not a pointer to it. func make(t Type, size ...IntegerType) Type
即内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象 跟 new 类似,第一个参数也是一个类型而不是一个值,跟 new 不同的是,make 返回类型的引 用而不是指针,而返回值也依赖于具体传入的类型
注意:只能用在这三种类型上
总结:
new和其他语言中的同名函数一样: new(t)分配了零值填充的T类型的内存空间,并且返回其地址,即一个t类型的值。 它并不初始化内存,只是将其置零。t指向的内容的值为零(zero value)。注意并不是指针为 零。
make(t, args)与new(t)的功能区别是,make只能创建slice、map和channel,,并且返回一个初始化的 (而不是置零),类型为t的值(而不是*t)。
派生数据结构的源码:
slice
type slice struct { array unsafe.Pointer len int cap int }
slice的结构体由3部分构成,Pointer 是指向一个数组的指针,len 代表当前切片的长度,cap 是 当前切片的容量
map
// A header for a Go map. type hmap struct { count int flags uint8 B uint8 noverflow uint16 hash0 uint32 buckets unsafe.Pointer oldbuckets unsafe.Pointer nevacuate uintptr extra *mapextra }
channe
type hchan struct { qcount uint dataqsiz uint buf unsafe.Pointer elemsize uint16 closed uint32 elemtype *_type sendx uint recvx uint recvq waitq sendq waitq lock mutex }
可以看出三个类型的背后都引用了 使用前必须初始化 的数据结构
而只有make 用于可以初始化其内部的数据结构并准备好将要使用的值
二者都是内存的分配(堆上),但是make只用于slice、map以及channel的初始化(非零值); 而new用于类型的内存分配,并且内存置为零。所以在我们编写程序的时候,就可以根据自己的 需要很好的选择了。
make返回的还是这三个引用类型本身;而new返回的是指向类型的指针。
所以有new这个内置函数,可以给我们分配一块内存让我们使用,但是现实的编码中,它是不常 用的。我们通常都是采用短语句声明以及结构体的字面量达到我们的目的