Golan中?new()?、?make()?和簡短聲明符的區(qū)別和使用
詳細介紹Golang的new() 、 make() 和簡短聲明符的區(qū)別和使用。

文章目錄 `new()` 函數(shù)`make()` 函數(shù)對于不同類型的說明 簡短聲明 `:=``new()`、`make()` 和 `:=` 的比較總結補充普通變量聲明并后續(xù)初始化初始化切片初始化映射初始化通道
在 Go 語言中, new() 和 make() 都是用來分配內存的內建函數(shù),但是有很大區(qū)別。
new() 函數(shù)
new() 函數(shù)用于 分配內存并返回一個指向類型的指針。它會根據(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:可以是任何類型(包括基礎類型、結構體、數(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),并返回一個已經初始化的(且可以使用的)對象。
make()的作用不僅僅是分配內存,它還會 初始化數(shù)據(jù)結構的內部狀態(tài)(比如切片的長度、容量,映射的哈希表等)。make()只能用于 切片、映射和通道,而不能用于其他類型(比如結構體或數(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:對于切片和通道,這是它的長度;對于映射,這是它的初始大?。▋炔抗1淼拇笮。?。capacity:對于切片,這個參數(shù)是可選的,用來指定切片的容量。如果不指定容量,容量將等于長度。Map和Channel沒有這個參數(shù)。
對于不同類型的說明
切片(Slice):
- 長度:
size參數(shù)指定切片的長度,必傳。 - 容量:可選參數(shù),切片的容量等于它的長度。如果指定了第二個參數(shù)
capacity,則表示切片的容量。capacity必須大于或等于size。
為了避免意外修改原切片數(shù)據(jù),可以通過切片的第三個索引限制容量,從而在擴容時強制觸發(fā)新底層數(shù)組的創(chuàng)建。
映射(Map):
size參數(shù)可選。make 為映射分配內存,并根據(jù)指定的 元素數(shù)量 初始化映射。可以提供一個整數(shù)參數(shù)來指定映射的初始容量。如果沒有指定容量,Go 會為映射分配一個小的默認容量。
通道(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()返回的是已經初始化的對象(切片、映射或通道本身),并且可以直接使用。
示例:
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 會自動推導出變量的類型,并給它賦予一個初始值。 :=可以與 make() 和 new() 結合使用,簡化變量聲明和初始化過程,上面make()和new()的示例中已有展示結合使用,當然也可以不與make()和new()結合使用。如下,直接進行變量聲明。
示例:
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() | := |
|---|---|---|---|
| 用法 | 用于任何類型(包括基礎類型、結構體、數(shù)組等) | 僅用于 slice、map 和 channel 類型 | 用于聲明變量并初始化為零值或指定值 |
| 返回值 | 返回類型的指針,指向零值 | 返回初始化后的對象,已經可以使用 | 返回值,而非指針 |
| 初始化內容 | 只會分配內存并初始化為零值 | 根據(jù)類型進行初始化(例如,初始化切片的長度和容量,初始化映射的哈希表) | 直接創(chuàng)建變量并賦初值(默認為零值) |
| 支持類型 | 所有類型 | slice、map、channel | 所有類型(包括切片、映射、通道、基礎類型) |
| 返回類型 | 類型的指針(例如 *int,*struct 等) | 對象本身(例如切片、映射、通道) | 變量本身(值類型或引用類型) |
| 內存分配 | 分配零值內存并返回指針 | 分配并初始化內存,返回已初始化的對象 | 分配并初始化變量 |
| 適用場景 | 創(chuàng)建指向零值的指針,通常用于結構體或基本類型 | 用于切片、映射、通道的內存分配和初始化 | 用于直接創(chuàng)建并初始化變量,不涉及指針 |
總結
new()用于為任意類型分配內存并返回該類型的指針,默認值為零值。make()用于初始化切片、映射和通道,并返回已初始化的對象。它不僅分配內存,還為這些類型做了額外的初始化工作。:=可以 make() 和 new() 結合使用,簡化變量聲明和初始化過程。
補充
上面主要講的是 new() 、 make() 函數(shù)的區(qū)別,也講了一點簡短聲明符 := (這算Go所特有的)。當然,也可以進行不使用new() 、 make() 和 := ,而是使用var先聲明,再進行初始化(slice,map,channle必須初始化,不能直接賦值,聲明后未初始化會導致 panic)。
- 使用
var聲明時,slice、map和channel的零值是nil,它們必須經過初始化才能使用。 - 初始化方法:
- 使用
make():最常見的初始化方式,適用于slice、map和channel。 - 使用字面量語法(s := []int{1, 2, 3} // 切片字面量):對于
slice和map,可以使用字面量語法進行初始化。
- 使用
- 未初始化的
nil類型不能直接使用,否則會導致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 或其他方式進行初始化
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
}到此這篇關于Golan中 new() 、 make() 和簡短聲明符的文章就介紹到這了,更多相關go new()和make()聲明符內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于golang channel實現(xiàn)的輕量級異步任務分發(fā)器示例代碼
這篇文章主要給大家介紹了關于基于golang channel實現(xiàn)的輕量級異步任務分發(fā)器的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-07-07

