Go 語言為什么建議定義零值可用的結構體?
?1.介紹
在 Go 語言中,通過聲明或者通過調用 new 為變量分配存儲空間,或者通過復合字面量或調用 make 創(chuàng)建新值時。
如果未提供顯式初始化,則會為變量或值指定默認值,此類變量或值的每個元素都設置為其類型的零值。
2.Golang 類型的零值
在 Go 語言中,原生類型都有默認值,即類型的零值。
- 布爾型的零值:false
- 整型的零值:0
- 字符串類型的零值:""
- 指針、函數(shù)、接口、切片、通道、映射的零值:nil
需要注意的是,Go 語言類型的零值初始化是遞歸完成的,即數(shù)組、結構體的每個元素都進行零值初始化。
3.Golang 定義零值可用的結構體
在 Go 語言中,定義零值可用的結構體不僅對程序的安全性和正確性非常重要,它還可以無需預先顯式初始化即可直接使用,使 Go 程序代碼更優(yōu)雅。
盡量定義零值可用的結構體
例如 Go 標準庫 sync? 中的 sync.Mutex 結構體,它就是被定義為零值可用的結構體類型。
type Mutex struct {
state int32
sema uint32
}
因為 sync.Mutex? 包含兩個不可導出的整型字段,所以聲明 sync.Mutex 類型的值時,它的字段的值都被設置為 0。
在我們使用 sync.Mutex 時,無需預先顯式初始化,即可直接使用。
但是,需要注意的是,sync.Mutex 類型的變量在被使用之后,不能被復制。
切片類型是零值可用的類型
雖然我們在 Part 02 中講到,切片的零值是 nil,我們知道,對于值為 nil 的變量,需要預先為其進行賦值(可用的值)之后,我們才可以使用該變量。
但是 Golang 的切片類型比較特殊,它是零值可用的類型,我們可以直接對其進行 append 操作,而不會觸發(fā)引用 nil 的錯誤。
示例代碼:
var id []int
id = append(id, 1)
id = append(id, 2)
fmt.Println(id)
閱讀上面這段代碼,我們聲明一個元素為整型的切片類型的變量 id,在未預先對其進行顯式初始化的情況下,直接使用 append 函數(shù)為其追加數(shù)據(jù),結果是可以正常執(zhí)行,未觸發(fā)引用 nil 變量的錯誤。
但是,切片類型作為零值可用的類型,也有其局限性,以上示例代碼中,我們不能通過下標的方式操作切片的值。
指針類型的零值
另一個比較特殊的類型是指針,我們在 Part 02 講到,指針的零值也是 nil,但是 nil 指針可以調用其類型的方法。
示例代碼:
type User struct {
Id int
Name string
}
func (u *User) UserInfo() string {
if u == nil {
return "Not found"
}
return fmt.Sprintf("{id:%d,name:%s}", u.Id, u.Name)
}
var u1 *User
data := u1.UserInfo()
fmt.Println(data)
4.總結
本文我們介紹 Go 語言的每個原生類型都會有默認值,即零值。
通過列舉 Go 標準庫 sync.Mutex 結構體類型,介紹在 Go 語言中,定義零值可用的結構體的好處。
順便提到零值為 nil 的切片和指針兩種類型的特殊之處。