天天看點

Golang的記憶體配置設定make,new詳解Golang的記憶體配置設定make,new詳解NewMake大括号(Composite literals)

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的取值:

  1. 取值範圍必須要是int,一定是正數
  2. 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,對裡面的每個值做初始化,并傳回