make
用於內建類型(map
、slice
和channel
)的內存分配。new
用於各類類型的內存分配。git
內建函數new
本質上說跟其它語言中的同名函數功能同樣:new(T)
分配了零值填充的T
類型的內存空間,而且返回其地址,即一個*T
類型的值。用Go的術語說,它返回了一個指針,指向新分配的類型T
的零值。有一點很是重要:github
new
返回指針。golang
內建函數make(T, args)
與new(T)
有着不一樣的功能,make只能建立slice
、map
和channel
,而且返回一個有初始值(非零)的T
類型,而不是*T
。本質來說,致使這三個類型有所不一樣的緣由是指向數據結構的引用在使用前必須被初始化。例如,一個slice
,是一個包含指向數據(內部array
)的指針、長度和容量的三項描述符;在這些項目被初始化以前,slice
爲nil
。對於slice
、map
和channel
來講,make
初始化了內部的數據結構,填充適當的值。web
make
返回初始化後的(非零)值。數據結構
下面這個圖詳細的解釋了new
和make
之間的區別。app
圖2.5 make和new對應底層的內存分配函數
關於「零值」,所指並不是是空值,而是一種「變量未填充前」的默認值,一般爲0。 此處羅列 部分類型 的 「零值」ui
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 ""
代碼示例:spa
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))
輸出:.net
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