詳解Go語言中new和make關(guān)鍵字的區(qū)別
本篇文章來介紹一道非常常見的面試題,到底有多常見呢?可能很多面試的開場白就是由此開始的。那就是 new 和 make 這兩個內(nèi)置函數(shù)的區(qū)別。
其實這個問題本身并不復(fù)雜,簡單來說就是,new 只分配內(nèi)存,而 make 只能用于 slice、map 和 chan 的初始化,下面我們就來詳細介紹一下。
new
new 是一個內(nèi)置函數(shù),它會分配一段內(nèi)存,并返回指向該內(nèi)存的指針。
其函數(shù)簽名如下:
源碼
//?The?new?built-in?function?allocates?memory.?The?first?argument?is?a?type, //?not?a?value,?and?the?value?returned?is?a?pointer?to?a?newly //?allocated?zero?value?of?that?type. func?new(Type)?*Type
從上面的代碼可以看出,new 函數(shù)只接受一個參數(shù),這個參數(shù)是一個類型,并且返回一個指向該類型內(nèi)存地址的指針。
同時 new 函數(shù)會把分配的內(nèi)存置為零,也就是類型的零值。
使用
使用 new 函數(shù)為變量分配內(nèi)存空間:
p1?:=?new(int) fmt.Printf("p1?-->?%#v?\n?",?p1)?//(*int)(0xc42000e250)? fmt.Printf("p1?point?to?-->?%#v?\n?",?*p1)?//0 var?p2?*int i?:=?0 p2?=?&i fmt.Printf("p2?-->?%#v?\n?",?p2)?//(*int)(0xc42000e278)? fmt.Printf("p2?point?to?-->?%#v?\n?",?*p2)?//0
上面的代碼是等價的,new(int)
將分配的空間初始化為 int 的零值,也就是 0,并返回 int 的指針,這和直接聲明指針并初始化的效果是相同的。
當然,new 函數(shù)不僅能夠為系統(tǒng)默認的數(shù)據(jù)類型分配空間,自定義類型也可以使用 new 函數(shù)來分配空間,如下所示:
type?Student?struct?{ ???name?string ???age?int } var?s?*Student s?=?new(Student)?//分配空間 s.name?=?"zhangsan" fmt.Println(s)
這就是 new 函數(shù),它返回的永遠是類型的指針,指針指向分配類型的內(nèi)存地址。需要注意的是,new 函數(shù)只會分配內(nèi)存空間,但并不會初始化該內(nèi)存空間。
make
make 也是用于內(nèi)存分配的,但是和 new 不同,它只用于 slice、map 和 chan 的內(nèi)存創(chuàng)建,而且它返回的類型就是這三個類型本身,而不是他們的指針類型。因為這三種類型本身就是引用類型,所以就沒有必要返回他們的指針了。
其函數(shù)簽名如下:
源碼
//?The?make?built-in?function?allocates?and?initializes?an?object?of?type //?slice,?map,?or?chan?(only).?Like?new,?the?first?argument?is?a?type,?not?a //?value.?Unlike?new,?make's?return?type?is?the?same?as?the?type?of?its //?argument,?not?a?pointer?to?it.?The?specification?of?the?result?depends?on //?the?type: //?Slice:?The?size?specifies?the?length.?The?capacity?of?the?slice?is //?equal?to?its?length.?A?second?integer?argument?may?be?provided?to //?specify?a?different?capacity;?it?must?be?no?smaller?than?the //?length,?so?make([]int,?0,?10)?allocates?a?slice?of?length?0?and //?capacity?10. //?Map:?An?empty?map?is?allocated?with?enough?space?to?hold?the //?specified?number?of?elements.?The?size?may?be?omitted,?in?which?case //?a?small?starting?size?is?allocated. //?Channel:?The?channel's?buffer?is?initialized?with?the?specified //?buffer?capacity.?If?zero,?or?the?size?is?omitted,?the?channel?is //?unbuffered. func?make(t?Type,?size?...IntegerType)?Type
通過上面的代碼可以看出 make 函數(shù)的 t
參數(shù)必須是 slice、map 和 chan 中的一個,并且返回值也是類型本身。
使用
下面用 slice 來舉一個例子:
var?s1?[]int if?s1?==?nil?{ ????fmt.Printf("s1?is?nil?-->?%#v?\n?",?s1)?//?[]int(nil) } s2?:=?make([]int,?3) if?s2?==?nil?{ ????fmt.Printf("s2?is?nil?-->?%#v?\n?",?s2) }?else?{ ????fmt.Printf("s2?is?not?nill?-->?%#v?\n?",?s2)//?[]int{0,?0,?0} }
slice 的零值是 nil
,但使用 make 初始化之后,slice 內(nèi)容被類型 int 的零值填充,如:[]int{0, 0, 0}
。
map 和 chan 也是類似的,就不多說了。
總結(jié)
通過以上分析,總結(jié)一下 new 和 make 主要區(qū)別如下:
- make 只能用來分配及初始化類型為 slice、map 和 chan 的數(shù)據(jù)。new 可以分配任意類型的數(shù)據(jù);
- new 分配返回的是指針,即類型
*Type
。make 返回類型本身,即Type
; - new 分配的空間被清零。make 分配空間后,會進行初始化;
到此這篇關(guān)于詳解Go語言中new和make關(guān)鍵字的區(qū)別的文章就介紹到這了,更多相關(guān)Go語言 new make內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang使用singleflight解決并發(fā)重復(fù)請求
高并發(fā)的場景下,經(jīng)常會出現(xiàn)并發(fā)重復(fù)請求資源的情況,singleflight是golang內(nèi)置的一個包,這個包提供了對重復(fù)函數(shù)調(diào)用的抑制功能,所以下面我們就來看看如何使用它解決并發(fā)重復(fù)請求吧2023-08-08golang socket斷點續(xù)傳大文件的實現(xiàn)方法
今天小編就為大家分享一篇golang socket斷點續(xù)傳大文件的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07GO使用socket和channel實現(xiàn)簡單控制臺聊天室
今天小編給大家分享一個簡單的聊天室功能,聊天室主要功能是用戶可以加入離開聊天室,實現(xiàn)思路也很簡單明了,下面小編給大家?guī)砹送暾a,感興趣的朋友跟隨小編一起看看吧2021-12-12