Golang中make與new使用區(qū)別小結
前言
本文主要給大家介紹了Go語言中函數(shù)new與make的使用和區(qū)別,關于Go語言中new和make是內建的兩個函數(shù),主要用來創(chuàng)建分配類型內存。在我們定義生成變量的時候,可能會覺得有點迷惑,不知道什么時候該使用make,什么時候該使用new,其實他們的規(guī)則很簡單,下面我們就通過一些示例說明他們的區(qū)別和使用。
變量的聲明
var i int var s string
? 變量的聲明我們可以通過var關鍵字,然后就可以在程序中使用。當我們不指定變量的默認值時,這些變量的默認值是他們的零值,比如int類型的零值是0,string類型的零值是"",引用類型的零值是nil。
對于例子中的兩種類型的聲明,我們可以直接使用,對其進行賦值輸出。但是如果我們換成指針類型呢?
test1.go
package main import ( "fmt" ) func main() { var i *int *i=10 fmt.Println(*i) }
$ go run test1.go panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4849df] goroutine 1 [running]: main.main() /home/onenewcode/go/src/golang_deeper/make_new/t
從這個提示中可以看出,對于引用類型的變量,我們不光要聲明它,還要為它分配內容空間,否則我們的值放在哪里去呢?這就是上面錯誤提示的原因。
對于值類型的聲明不需要,是因為已經(jīng)默認幫我們分配好了。
因為要分配內存,就引出來今天的內存分配函數(shù)new和make。
new
對于上面的問題我們如何解決呢?既然我們知道了沒有為其分配內存,那么我們使用new分配一個吧。
func main() { var i *int i=new(int) *i=10 fmt.Println(*i) }
現(xiàn)在再運行程序,完美PASS,打印10?,F(xiàn)在讓我們看下new這個內置的函數(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
把上面的英語翻譯可以得出以下信息:
它只接受一個參數(shù),這個參數(shù)是一個類型,分配好內存后,返回一個指向該類型內存地址的指針。同時請注意它同時把分配的內存置為零,也就是類型的零值。
我們的例子中,如果沒有*i=10,那么打印的就是0。這里體現(xiàn)不出來new函數(shù)這種內存置為零的好處,我們再看一個例子。
test2.go
package main import ( "fmt" "sync" ) type user struct { lock sync.Mutex name string age int } func main() { u := new(user) //默認給u分配到內存全部為0 u.lock.Lock() //可以直接使用,因為lock為0,是開鎖狀態(tài) u.name = "張三" u.lock.Unlock() fmt.Println(u) }
運行
$ go run test2.go
&{{0 0} 張三 0}
示例中的user類型中的lock字段我不用初始化,直接可以拿來用,不會有無效內存引用異常,因為它已經(jīng)被零值了。
這就是new,它返回的永遠是類型的指針,指向分配類型的內存地址。
make
make也是用于內存分配的,但是和new不同。
它只用于,chan,map,slice的內存創(chuàng)建,而且它返回的類型就是這三個類型本身,而不是他們的指針類型,因為這三種類型就是引用類型,所以就沒有必要返回他們的指針了。
注意,因為這三種類型是引用類型,所以必須得初始化,但是不是置為零值,這個和new是不一樣的。
func make(t Type, size ...IntegerType) Type
從函數(shù)聲明中可以看到,返回的還是該類型。
make與new的異同
相同點:
- 都是內建函數(shù),用于內存管理。
- 都涉及到動態(tài)內存的分配。
不同點:
用途和適用類型:
- new(T):適用于任何類型的內存分配,包括但不限于結構體、數(shù)組、指針等。它會為指定的類型 T 分配內存,并將內存初始化為其零值,然后返回指向該內存區(qū)域的指針(類型為 *T)。
- make(T, args…):僅適用于三個內建的引用類型,即切片(slice)、映射(map)和通道(channel)。對于這三種類型,make 不僅僅是分配內存,還會執(zhí)行額外的初始化操作,如設置內部數(shù)據(jù)結構、哈希表大小以及 channel 緩沖區(qū)等。make 函數(shù)的返回值直接是初始化后的 slice/map/channel 類型,而不是指針。
使用方式和返回值:
- new() 的調用形式相對簡單:p := new(Type),返回的是一個指向新分配內存的指針。
- make() 的調用需要提供額外參數(shù)以初始化相應的類型,例如創(chuàng)建切片時需要長度和可選的容量:s := make([]int, length, capacity);創(chuàng)建 map 或 channel 時無需指定大小,但可以對通道指定緩沖區(qū)大小。
初始化內容:
new() 只做最基本的內存分配并填充零值。
make() 初始化的內容更復雜,例如:
- 對于切片,會創(chuàng)建底層數(shù)組并設置長度和容量;
- 對于映射,會初始化一個空的哈希表;
- 對于通道,會創(chuàng)建一個通信的數(shù)據(jù)結構,并可選擇性地分配緩沖區(qū)。
總之,在 Go 語言中,當你需要為自定義類型或基本類型分配內存且不涉及特定初始化邏輯時,使用 new();而當你需要初始化 slice、map 或 channel 這些內建的引用類型時,則必須使用 make()。
到此這篇關于Golang中make與new使用區(qū)別小結的文章就介紹到這了,更多相關Golang make與new內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Golang科學計數(shù)法轉換string數(shù)字輸出的實現(xiàn)
最近接手一個商城運單號模塊,接手后發(fā)現(xiàn)有部分運單號返回給前端是按照科學計數(shù)法的方式返回,本文就介紹一下Golang科學計數(shù)法轉換string數(shù)字輸出,感興趣的可以了解一下2021-07-07go語言題解LeetCode1299將每個元素替換為右側最大元素
這篇文章主要為大家介紹了go語言LeetCode刷題1299將每個元素替換為右側最大元素示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01GO?CountMinSketch計數(shù)器(布隆過濾器思想的近似計數(shù)器)
這篇文章主要介紹了GO?CountMinSketch計數(shù)器(布隆過濾器思想的近似計數(shù)器),文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-09-09