聊聊Golang的Make和New函數
今天在聊make和new函數之前,咱們先來看一種現象 當然如果你對golang的指針還不是很了解,可以先看看這篇文章,以做到無縫連接
。看完這個,我徹底理解了golang的指針。
case1?
這個例子很簡單,咱們定義了一個int類型的變量,然后賦值直接輸出,這個沒什么好疑問的,但是咱們把這個例子改一下
case2?
請問上面代碼會輸出什么?不出意外會輸出10對不對,但是咱們運行之后,命令行卻輸出
這是為什么呢?
簡單說說原因:
因為我們在var p *int,只是把p變量定義為了指針類型,p的默認值為nil,「并沒有在內存上分配對應的空間」,既然沒有空間,那給p變量賦值自然就會報錯,當然p任然是占空間的,只不過p的值為nil
如果我們把代碼改成下面這樣:
結果就可以正常輸出,為什么加個new就可以正常輸出呢?想要回答這個問題,首先你得知道new函數做了什么。
new函數主要做了下面三件事
- 調用操作系統接口申請一塊int類型的內存空間
- 操作系統將分配的空間返回給go程序
- 在內存中開辟了一塊int的空間,并且把該空間的指針指向p 因為現在指針p已經指向了一塊被分配的空間,所以可以直接進行賦值操作
小結?
對于int,string,float,rune,byte,bool等類型,在定義變量的時候系統已經給申請了內存,而且給了對應的默認值(int的默認值為0,string的默認值為"",bool的默認值為false),所以我們可以直接給變量進行賦值操作。
對于指針,切片,map等類型,這些變量直接定義的時候系統是沒有給分配內存的,并且默認值為nil,所以不能直接賦值。如果想賦值的話,需要用new或者make函數向系統提前申請內存才行。
make和new的區別?
make和new都是用來內存分配的方法,簡單的說,new只分配內存,
- 「make用于slice,map,和channel的初始化,不僅可以開辟一個內存,還能給這個內存的類型初始化其零值」。
- make返回的還是引用類型本身;而new返回的是指向類型的指針。
make
new
make只能用來分配及初始化類型為slice,map,channel的數據;new可以分配任意類型的數據。