Golan中?new()?、?make()?和簡短聲明符的區(qū)別和使用
詳細(xì)介紹Golang的new() 、 make() 和簡短聲明符的區(qū)別和使用。
文章目錄 `new()` 函數(shù)`make()` 函數(shù)對于不同類型的說明 簡短聲明 `:=``new()`、`make()` 和 `:=` 的比較總結(jié)補充普通變量聲明并后續(xù)初始化初始化切片初始化映射初始化通道
在 Go 語言中, new()
和 make()
都是用來分配內(nèi)存的內(nèi)建函數(shù),但是有很大區(qū)別。
new()
函數(shù)
new()
函數(shù)用于 分配內(nèi)存并返回一個指向類型的指針。它會根據(jù)類型分配零值并返回該類型的地址。
源碼:
// 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
Type
:可以是任何類型(包括基礎(chǔ)類型、結(jié)構(gòu)體、數(shù)組等)。
返回值:
new()
返回一個指向類型的指針。該類型的值會被初始化為其 零值(例如,整數(shù)為 0,布爾值為false
,指針為nil
,字符串為空字符串等)。
示例:
package main import "fmt" func main() { // 使用 new 創(chuàng)建一個 int 類型的指針 p := new(int) // new 返回的是指向 int 的指針,指針的初始值是零值,即 0 fmt.Println(*p) // 輸出: 0 *p = 42 // 修改 p 指向的值 fmt.Println(*p) // 輸出: 42 }
make()
函數(shù)
make()
函數(shù)用于 初始化切片(slice)、映射(map)和通道(channel),并返回一個已經(jīng)初始化的(且可以使用的)對象。
make()
的作用不僅僅是分配內(nèi)存,它還會 初始化數(shù)據(jù)結(jié)構(gòu)的內(nèi)部狀態(tài)(比如切片的長度、容量,映射的哈希表等)。make()
只能用于 切片、映射和通道,而不能用于其他類型(比如結(jié)構(gòu)體或數(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. For example, make([]int, 0, 10) allocates an underlying array // of size 10 and returns a slice of length 0 and capacity 10 that is // backed by this underlying array. // 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
Type
:要創(chuàng)建的類型,可以是slice
、map
或channel
。size
:對于切片和通道,這是它的長度;對于映射,這是它的初始大?。▋?nèi)部哈希表的大小)。capacity
:對于切片,這個參數(shù)是可選的,用來指定切片的容量。如果不指定容量,容量將等于長度。Map和Channel沒有這個參數(shù)。
對于不同類型的說明
切片(Slice):
- 長度:
size
參數(shù)指定切片的長度,必傳。 - 容量:可選參數(shù),切片的容量等于它的長度。如果指定了第二個參數(shù)
capacity
,則表示切片的容量。capacity
必須大于或等于size
。
為了避免意外修改原切片數(shù)據(jù),可以通過切片的第三個索引限制容量,從而在擴容時強制觸發(fā)新底層數(shù)組的創(chuàng)建。
映射(Map):
size
參數(shù)可選。make
為映射分配內(nèi)存,并根據(jù)指定的 元素數(shù)量 初始化映射??梢?strong>提供一個整數(shù)參數(shù)來指定映射的初始容量。如果沒有指定容量,Go 會為映射分配一個小的默認(rèn)容量。
通道(Channel):
size
參數(shù)可選。make
用于創(chuàng)建一個 帶緩沖區(qū)的通道,size
參數(shù)指定通道的 緩沖區(qū)容量。- 如果沒有指定
size
或指定為0
,則創(chuàng)建一個 無緩沖通道,即通道會阻塞直到接收方接收數(shù)據(jù)。
同時,在使用 len()
和 cap()
時候注意:
- 切片(slice):
len
返回元素的數(shù)量,cap
返回底層數(shù)組的容量。 - 映射(map):
len
返回鍵值對的數(shù)量,但沒有cap
函數(shù)。 - 通道(channel):
len
返回通道中的元素數(shù)量,cap
返回通道的緩沖區(qū)容量。
返回值:
make()
返回的是已經(jīng)初始化的對象(切片、映射或通道本身),并且可以直接使用。
示例:
package main import "fmt" func main() { // 創(chuàng)建一個長度為 5 的整數(shù)切片 slice := make([]int, 5) fmt.Println(slice) // 輸出: [0 0 0 0 0] // 創(chuàng)建一個長度為 3,容量為 5 的切片 slice2 := make([]int, 3, 5) fmt.Println(slice2) // 輸出: [0 0 0] // 創(chuàng)建一個容量為 10 的整數(shù)通道 ch := make(chan int, 10) ch <- 42 // 向通道中發(fā)送數(shù)據(jù) fmt.Println(<-ch) // 輸出: 42 // 創(chuàng)建一個具有初始大小的映射 m := make(map[string]int) m["key"] = 10 fmt.Println(m) // 輸出: map[key:10] }
簡短聲明 :=
- 使用 Go 中的簡短聲明符
:=
時,可以同時聲明和初始化這些類型。不需要手動聲明變量類型,Go 會自動推導(dǎo)出變量的類型,并給它賦予一個初始值。 :=
可以與 make() 和 new() 結(jié)合使用,簡化變量聲明和初始化過程,上面make()
和new()
的示例中已有展示結(jié)合使用,當(dāng)然也可以不與make()
和new()
結(jié)合使用。如下,直接進(jìn)行變量聲明。
示例:
package main import "fmt" func main() { // 使用 := 創(chuàng)建并初始化一個 map m := map[string]int{ "apple": 5, "banana": 3, "orange": 2, } // 輸出 map 中的元素 fmt.Println(m) // 輸出: map[apple:5 banana:3 orange:2] }
這里,p := 0
創(chuàng)建了一個類型為 int
的變量 p
,并將其初始化為 0
,而不是指向 0
的指針。p
本身是一個值,而不是一個指針。
new()
、make()
和 :=
的比較
特性 | new() | make() | := |
---|---|---|---|
用法 | 用于任何類型(包括基礎(chǔ)類型、結(jié)構(gòu)體、數(shù)組等) | 僅用于 slice 、map 和 channel 類型 | 用于聲明變量并初始化為零值或指定值 |
返回值 | 返回類型的指針,指向零值 | 返回初始化后的對象,已經(jīng)可以使用 | 返回值,而非指針 |
初始化內(nèi)容 | 只會分配內(nèi)存并初始化為零值 | 根據(jù)類型進(jìn)行初始化(例如,初始化切片的長度和容量,初始化映射的哈希表) | 直接創(chuàng)建變量并賦初值(默認(rèn)為零值) |
支持類型 | 所有類型 | slice 、map 、channel | 所有類型(包括切片、映射、通道、基礎(chǔ)類型) |
返回類型 | 類型的指針(例如 *int ,*struct 等) | 對象本身(例如切片、映射、通道) | 變量本身(值類型或引用類型) |
內(nèi)存分配 | 分配零值內(nèi)存并返回指針 | 分配并初始化內(nèi)存,返回已初始化的對象 | 分配并初始化變量 |
適用場景 | 創(chuàng)建指向零值的指針,通常用于結(jié)構(gòu)體或基本類型 | 用于切片、映射、通道的內(nèi)存分配和初始化 | 用于直接創(chuàng)建并初始化變量,不涉及指針 |
總結(jié)
new()
用于為任意類型分配內(nèi)存并返回該類型的指針,默認(rèn)值為零值。make()
用于初始化切片、映射和通道,并返回已初始化的對象。它不僅分配內(nèi)存,還為這些類型做了額外的初始化工作。:=
可以 make() 和 new() 結(jié)合使用,簡化變量聲明和初始化過程。
補充
上面主要講的是 new() 、 make() 函數(shù)的區(qū)別,也講了一點簡短聲明符 := (這算Go所特有的)。當(dāng)然,也可以進(jìn)行不使用new() 、 make() 和 := ,而是使用var
先聲明,再進(jìn)行初始化(slice,map,channle必須初始化,不能直接賦值,聲明后未初始化會導(dǎo)致 panic)。
- 使用
var
聲明時,slice
、map
和channel
的零值是nil
,它們必須經(jīng)過初始化才能使用。 - 初始化方法:
- 使用
make()
:最常見的初始化方式,適用于slice
、map
和channel
。 - 使用字面量語法(s := []int{1, 2, 3} // 切片字面量):對于
slice
和map
,可以使用字面量語法進(jìn)行初始化。
- 使用
- 未初始化的
nil
類型不能直接使用,否則會導(dǎo)致panic
。
普通變量聲明并后續(xù)初始化
package main import "fmt" func main() { var x int // 聲明一個變量 x,類型是 int,零值是 0 fmt.Println(x) // 輸出 0 // 后續(xù)賦值 x = 10 fmt.Println(x) // 輸出 10 }
初始化切片
package main import "fmt" func main() { var s []int // 聲明一個切片,零值是 nil fmt.Println(s) // 輸出: [] // 后續(xù)使用 append 或其他方式進(jìn)行初始化 s = append(s, 1, 2, 3) fmt.Println(s) // 輸出: [1 2 3] }
初始化映射
package main import "fmt" func main() { var m map[string]int // 聲明一個映射,零值是 nil fmt.Println(m) // 輸出: map[] // 后續(xù)初始化映射 m = make(map[string]int) m["apple"] = 5 m["banana"] = 3 fmt.Println(m) // 輸出: map[apple:5 banana:3] }
初始化通道
package main import "fmt" func main() { var ch chan int // 聲明一個通道,零值是 nil fmt.Println(ch) // 輸出: <nil> // 后續(xù)初始化通道 ch = make(chan int, 3) ch <- 1 fmt.Println(<-ch) // 輸出: 1 }
到此這篇關(guān)于Golan中 new() 、 make() 和簡短聲明符的文章就介紹到這了,更多相關(guān)go new()和make()聲明符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于golang channel實現(xiàn)的輕量級異步任務(wù)分發(fā)器示例代碼
這篇文章主要給大家介紹了關(guān)于基于golang channel實現(xiàn)的輕量級異步任務(wù)分發(fā)器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07Go空結(jié)構(gòu)體struct{}的作用是什么
本文主要介紹了Go空結(jié)構(gòu)體struct{}的作用是什么,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02