Golang的記憶體配置設定make,new詳解
Golang記憶體配置設定主要有三種方式:new,make,以及大括号({})。常常在使用上容易混亂,弄不清楚。
New
采用New傳回的是一個指針,即指向一個被初始化為0值得位址。
p 是一個指針,指向一個類型為int的并被初始化為0的值。
type SyncedBuffer struct {
lock sync.Mutex
buffer bytes.Buffer
}
p := new(SyncedBuffer) // type *SyncedBuffer
var v SyncedBuffer // type SyncedBuffer
p 也是一個指針,指向一個類型為SyncedBuffer的值,這個值裡面lock,buffer全部被初始化為0.
是以可以看出,New可以用于資料類型,以及資料結構的記憶體配置設定,傳回一個位址,并将相關值全部初始化為0.
Make
make僅僅用于slice,map,channel的記憶體配置設定,與New不同的是,采用make配置設定記憶體,并不是傳回一個位址,而是直接傳回類型值,且值也不是被初始化為0,而是可以被指定初始化。
v是一個slice,根據slice的結構我們可以知道,len被初始化為10, cap被初始化100,而data被指向
一個10個元素的數組。假設如果用New會怎麼樣呢。
這個p一個指針,而裡面的值會被初始化為0,那麼就相當于*p == nil,一用就會奔潰。
Call Type T Result
make(T, n) slice slice of type T with length n and capacity n
make(T, n, m) slice slice of type T with length n and capacity m
make(T) map map of type T
make(T, n) map map of type T with initial space for approximately n elements
make(T) channel unbuffered channel of type T
make(T, n) channel buffered channel of type T, buffer size n
注意n和m的取值:
- 取值範圍必須要是int,一定是正數
- n ≤ m
大括号(Composite literals)
與make和new不同,{} 适用性比較廣, 并可直接指派初始化,可以用于slice,map,struct等等
f := new(File)
v := &File{}
t := &File{fd: fd, name: name}
如果不對類型做指派,那麼和new的效果是一樣的,f與v是等價的,也是被初始化為0,并傳回一個指針。當然如果不想被初始化為0,也可以針對每個值做指派,如t。
// Arrays
elements := []int{1, 2, 3, 4}
// Struct definition
type Thing struct {
name string
generation int
model string
}
// Positional fields
thing1 := Thing{"Raspberry Pi", 2, "B"}
// Explicit field names as key
thing2 := Thing{name: "Raspberry Pi", generation: 2, model: "B"}
用于arrays,struct, map,對裡面的每個值做初始化,并傳回