golang 內建函式new()和make()的區別
阿新 • • 發佈:2019-02-15
Go語言中的內建函式new和make是兩個用於記憶體分配的原語(allocation primitives),其功能相似,卻有本質區別。
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、map和channel要由make建立呢?
先來看一下以上三個資料結構的原始碼
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
}
channel
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 用於可以初始化
其內部的資料結構並準備好將要使用的值。