make 只用於 map、slice、channel
make不是通用的「建立東西」,它只吃這三種型別。因為只有這三種在使用前需要 runtime 先把內部結構初始化好。
make(map[string]int) // 配置雜湊表
make([]int, 0, 5) // 配置底層 array,並給定 len / cap
make(chan string) // 配置 channel 的佇列與同步機制它們的共通點是:型別本身只是一層外殼,真正的資料結構要另外配置——map 的雜湊表、slice 的底層 array、channel 的佇列。只用 var 宣告會得到一個沒有內部結構的 zero value(nil),能不能用要看型別:
| 型別 | var 宣告後直接用 |
|---|---|
| slice | ✅ 可以 append(會替它配置) |
| map | ❌ 寫入就 panic,見 nil map 可以讀但不能寫 |
| channel | ❌ 收送都會永遠卡住(deadlock) |
其他型別(int、string、struct、array)的 zero value 本身就能直接用,不需要 make。
跟 new 的差別
new(T) 配置一塊 T 的零值記憶體並回傳指標 *T;make 回傳的是型別本身(不是指標),而且會把內部結構初始化好。實務上 new 很少用,需要指標時通常寫 &T{}。
相關:Go 建立 map 的三種寫法、Slice 的四種建立方式與 nil、Channel 是 goroutine 之間的通訊管道