Golang 中make與new 區別
Golang 中make與new 區別
在 golang 有兩個保留字make
與new
,也是剛開始學習 golang 的時候容易搞混的地方,這邊做個簡單的筆記。
new
new 可以用來初始化泛型,並且返回儲存位址
。所以通常我們會用指標變數來接new
過後的型別。特別要注意的是,new 會自動用 zeroed value 來初始化型別,也就是字串會是""
,number 會是0
,channel, func, map, slice 等等則會是nil
。
因為這個特性,如果我們對 map 做以下的操作的話,會出現panic: assignment to entry in nil map
func main() { people := new(map[string]string) p := *people p["name"] = "Kalan" // panic: assignment to entry in nil map }
因為初始化的 map 會是 nil map,不像其他的 primitive type 一樣有預設值。
如果用struct
做初始化,也可以直接用&
代表指向的位址,下面兩個寫法效果是一樣的:
type Person struct { Name string Ageint } func main() { p := &Person{} p := new(Person) }
好處是上面的Person
也可以根據自己想要傳入的值額外再做設定,但 new 則是全部的 field 都會直接塞 zeroed value。
make
make
與new
不同,是用來初始化一些特別的型別,像是 channel, map, slice 等等。另外特別要注意的是make 並不會回傳指標
,如果要拿到指標,就要考慮用像是 new 的方式來初始化型別。
func main() { receiver := make(chan string) // 初始化 channel,但不回傳指標 person := make(map[string]string) people := make([]string, 100) // 初始化長度為 100 的字串陣列 }
還是要再度強調一次,make 不會回傳指標! 下面這段程式碼會噴錯:
func main() { person := make(map[string]string) fmt.Println(*person) // invalid indirect of person }
結論
make
與new
在剛開始學習 golang 時容易搞混,有時引數要傳入指標時也會一不小心就用 make 來傳,這時候知道這兩者的區別就相當重要。