Go語言new和make的區別

2021-10-23 13:39:40 字數 2371 閱讀 9235

go有兩種分配原語,分別為new和make。他們做的事情不同,並且處理不同的型別,這看上去讓人感到困惑,但是規則相當簡單。

new是乙個用來分配記憶體的內建函式(c++中是運算子),但他和大多數其他語言不同,new不會初始化記憶體(c++中會分配並呼叫建構函式),而是將記憶體歸0(也就是初始化成0)。即,new(t)給型別t分配了乙個儲存了0值的記憶體並且返回它的位址(在c++中相當於先呼叫malloc分配記憶體,然後呼叫memset初始化記憶體),返回的型別為**t*。用go的術語來說,new返回乙個指標,它指向新分配的t型別的零值的指標。

因為被new返回的記憶體是零值,當你在設計資料結構時,這非常有幫助。由於每個資料成員/欄位的型別都是零值,所以他們可以直接使用而不需要進一步地初始化。這意味著在使用這些資料結構時,可以直接通過new建立而不需要再做其他工作,他們就能正常使用。

有時候0值不能滿足我們的需求,我們需要乙個用於初始化的構造器。下面這個例子**於包os

func

newfile

(fd int

, name string

)*file

f :=

new(file)

f.fd = fd

f.name = name

f.dirinfo =

nil f.nepipe =

0return f

}

這看上去有點複雜,我們可以使用復合字面值(composite literals)來簡化它。復合字面值是乙個表示式,每當他被計算時,都會建立乙個新的例項。

func

newfile

(fd int

, name string

)*file

f := file

// 復合字面值

return

&f}

注意,和c語言不同,在go中允許返回乙個區域性變數的位址,和變數關聯的儲存空間在函式返回時繼續存活。實際上,獲取復合字面值的位址將在每次計算時為其分配乙個新的例項,因此我們可以將最後兩行結合起來。

return

&file

復合字面值的字段按順序排列並且必須全都存在。但是,通過顯式地列出元素,例如filed: value,初始化時可以為任意順序,剩下沒有被指定的字段為0值。因此我們可以將

return

&file

看成極限情況。如果復合文字不包含任何字段,則將建立乙個用於該型別的0值。表示式*new(file)和&file{}*等價。

復合字面值也可以用來建立陣列(array)、切片(slice)和對映(map)。

a :=

[...

]string

s :=

string

m :=

map[

int]

string

內建函式make(t, args)的目的不同於new(t)。它只用於建立切片、對映和通道(channel),它返回乙個t型別(不是*t型別)的被初始化了(不是0值)的值。和new的區別是,這三種型別為底層資料結構的引用,這些資料結構在使用前必須初始化。例如,切片的內部有三個元素,分別為:乙個指向資料(底層陣列)的指標,長度和容量。直到這些元素被初始化之前,切片的值為nil。對於切片、對映和通道,make會初始化內部的資料結構並且準備需要使用的值。例如

make([

]int,10

,100

)

分配乙個大小為100的陣列,然後建立乙個切片資料結構,長度為10,容量為100。而new(int)返回乙個0值的切片的資料結構,即乙個指向值為nil的切片。

下面的例子闡述了new和make的區別

var p *

int=

new(

int)

// 分配切片資料結構; *p == nil; 幾乎沒有作用

var v [

]int

=make([

]int

,100

)// 切片v引用乙個[100]int的陣列

// 沒有必要:

var p *

int=

new(

int)

*p =

make([

]int

,100

,100

)// 慣用做法:

v :=

make([

]int

,100

)

記住,make只應用於對映、切片和通道,並且不會返回指標。如果想獲得乙個顯式的指標,使用new分配空間或者直接獲取變數的位址。

go語言中new和make區別

new 和 make 是go語言的兩個內建函式,都是用來建立並分配記憶體,new函式只接受乙個引數,這個引數是乙個型別,並且返回乙個指向該型別記憶體位址的指標。而make只能用於 slice map 和 channel 的初始化,它返回的型別就是這三個型別本身,因為這3個本身就是引用型別,就不需要再...

go語言中make和new的區別

make用於內建型別 map slice 和channel 的記憶體分配。new用於各種型別的記憶體分配。內建函式new本質上說跟其他語言中的同名函式功能一樣 new t 分配了零值填充的t型別的記憶體空間,並且返回其位址,即乙個 t型別的值。用go語言的術語說,它返回了乙個指標,指向新分配的型別t...

go語言的new和make

golang的new和make主要區別如下 effective go舉了乙個例子,見 對於struct的分配和初始化,除了可以使用new外,還可以這樣做 t 例如 func testalloc t testing.t var t1 t t1 new t fmt.println t1 t2 t fmt...