天天看点

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,对里面的每个值做初始化,并返回