如有任何問題或建議,歡迎及時交流和碰撞。個人公衆號是 【腦子進煎魚了】,GitHub 地址: https://github.com/eddycjy。
你們好,我是煎魚。git
在 Go 語言中,有兩個比較雷同的內置函數,分別是 new
和 make
方法,其主要用途都是用於分配相應類型的內存空間。github
看上去 new
和 make
都是分配內存的,那他們有什麼區別呢?這個細節點也成爲了避免少 Go 語言工程師的面試題之一,值得你們一看。golang
在今天這篇文章中咱們未來解答這個問題。面試
在 Go 語言中,內置函數 make
僅支持 slice
、map
、channel
三種數據類型的內存建立,其返回值是所建立類型的自己,而不是新的指針引用。數據結構
函數簽名以下:架構
func make(t Type, size ...IntegerType) Type
具體使用示例:函數
func main() { v1 := make([]int, 1, 5) v2 := make(map[int]bool, 5) v3 := make(chan int, 1) fmt.Println(v1, v2, v3) }
在代碼中,咱們分別對三種類型調用了 make
函數進行了初始化。你會發現有的入參是有多個長度指定,有的沒有。微服務
這塊的區別主要是長度(len)和容量(cap)的指定,有的類型是沒有容量這一說法,所以天然也就沒法指定。spa
輸出結果:設計
[0] map[] 0xc000044070
有一個細節點要注意,調用 make
函數去初始化切片(slice)的類型時,會帶有零值,須要明確是否須要。
見過很多的小夥伴在這上面踩坑。
在 Go 語言中,內置函數 new
能夠對類型進行內存建立和初始化。其返回值是所建立類型的指針引用,與 make
函數在實質細節上存在區別。
函數簽名以下:
func new(Type) *Type
具體使用示例:
type T struct { Name string } func main() { v := new(T) v.Name = "煎魚" }
從上面的例子的效果來看,是否是似曾類似?其實與下面這種方式的同樣的:
func main() { v := T{} v.Name = "煎魚" }
輸出結果均是:
&{Name:煎魚}
其實 new
函數在平常工程代碼中是比較少見的,由於他可被替代。
通常會直接用快捷的 T{}
來進行初始化,由於常規的結構體都會帶有結構體的字面屬性:
func NewT() *T { return &T{Name: "煎魚"} }
這種初始化方式更方便。
可能會有的小夥伴會疑惑一點,就是 new
函數也能初始化 make
的三種類型:
v1 := new(chan bool) v2 := new(map[string]struct{})
那 make
函數的區別,優點是什麼呢?
本質上在於 make
函數在初始化時,會初始化 slice
、chan
、map
類型的內部數據結構,new
函數並不會。
例如:在 map
類型中,合理的長度(len)和容量(cap)能夠提升效率和減小開銷。
更進一步的區別:
make
函數:
channel
、map
、slice
三種類型。make
函數會對三種類型的內部數據結構(長度、容量等)賦值。new
函數:
在這篇文章中,咱們介紹了 Go 語言中 make
和 new
函數的使用,並針對其區別點進行了分析。
可能會有小夥伴疑惑,那 new
和 make
函數所初始化出來的內存,是分配在堆仍是棧上呢?
這就涉及到 Go 語言中的 「逃逸分析」 了(我公衆號前幾天的文章有發),若是所初始化的變量不須要在當前做用域外生存,那麼理論上就不須要初始化在堆上。
分享 Go 語言、微服務架構和奇怪的系統設計,歡迎你們關注個人公衆號和我進行交流和溝通。
最好的關係是互相成就,各位的點贊就是煎魚創做的最大動力,感謝支持。