make、new操作
make
用於內建類型(map
、slice
和channel
)的內存分配。new
用於各種類型的內存分配。
內建函數new
本質上說跟其它語言中的同名函數功能一樣:new(T)
分配了零值填充的T
類型的內存空間,並且返回其地址,即一個*T
類型的值。用Go的術語說,它返回了一個指針,指向新分配的類型T
的零值。有一點非常重要:
new
返回指針。
內建函數make(T, args)
與new(T)
有着不同的功能,make只能創建slice
、map
和channel
,並且返回一個有初始值(非零)的T
類型,而不是*T
。本質來講,導致這三個類型有所不同的原因是指向數據結構的引用在使用前必須被初始化。例如,一個slice
,是一個包含指向數據(內部array
)的指針、長度和容量的三項描述符;在這些項目被初始化之前,slice
為nil
。對於slice
、map
和channel
來說,make
初始化了內部的數據結構,填充適當的值。
make
返回初始化后的(非零)值。
下面這個圖詳細的解釋了new
和make
之間的區別。
圖2.5 make和new對應底層的內存分配
零值
關於“零值”,所指並非是空值,而是一種“變量未填充前”的默認值,通常為0。 此處羅列 部分類型 的 “零值”
int 0
int8 0
int32 0
int64 0
uint 0x0
rune 0 //rune的實際類型是 int32
byte 0x0 // byte的實際類型是 uint8
float32 0 //長度為 4 byte
float64 0 //長度為 8 byte
bool false
string ""
代碼示例:
var map1 map[string]string = make(map[string]string) fmt.Println(map1) fmt.Println(map1 == nil) var map2 *map[string]string = new(map[string]string) fmt.Println(map2) fmt.Println(map2 == nil) fmt.Println(*map2) fmt.Println(*map2 == nil) // var map1 map[string]string map1["aaa"] = "AAA" map1["bbb"] = "BBB" map1["ccc"] = "CCC" fmt.Println(map1) fmt.Println(len(map1))
輸出:
map[] false &map[] false map[] true map[bbb:BBB ccc:CCC aaa:AAA] 3 Success: process exited with code 0.
參考資料:
golang語言中map的初始化及使用: http://studygolang.com/articles/2379
Go語言中new()和 make()的區別詳解: http://www.jb51.net/article/56837.htm
golang深度拷貝map: http://blog.csdn.net/xtxy/article/details/51837400
golang 內置函數new() 和struct{} 初始化的區別: http://studygolang.com/articles/3377
https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/02.2.md