
这篇文章我们讨论下有关 Golang 中的零值(The zero value)、空值(nil)和空结构(The empty struct)的相关问题以及它们的一些用途。
零值
零值是指当你声明变量(分配内存)并未显式初始化时,始终为你的变量自动设置一个默认初始值的策略。
首先我们来看看官方有关零值(The zero value)的规范:
When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for numeric types, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.
据此我们可总结出:
- 对于值类型:布尔类型为
false
, 数值类型为0
,字符串为""
,数组和结构会递归初始化其元素或字段,即其初始值取决于元素或字段。 - 对于引用类型: 均为
nil
,包括指针 pointer,函数 function,接口 interface,切片 slice,管道 channel,映射 map。
通常,为你声明的变量赋予一个默认值是有用的,尤其是为你数组和结构中的元素或字段设置默认值,这是一种保证安全性和正确性的做法,同时也可以让你的代码保持简洁。
比如,下面的示例是我们常用的,结构体 Value
中包含两个 unexported 字段,sync.Mutex
中也有两个 unexported 字段。因为有默认零值,所以我们可以直接使用:
package main
import "sync"
type Value struct {
mu sync.Mutex
val int
}
func (v *Value)Incr(){
defer v.mu.Unlock()
v.mu.Lock()
v.val++
}
func main() {
var i Value
i.Incr()
}
因为切片是引用类型的,所以其零值也是 nil
:
package main
impor