内容: 记录go中的nil,其实跟C/C++中的NULL并不一样
Go中的nil:
零值在Go语言中:
* 布尔类型的"0"(初始值)为false
* 数值类型的"0"为0
* 字符串类型的"0"为空字符串""
* 而指针/切片/映射/通道/函数和接口的"0"即为nil。
* 结构体的零值与成员属性有关
例子:
当你声明一个结构体变量并未初始化时,该结构体所有的域(Field)都为"0"(初始值):
type Person struct {
Age int
Name string
Friend []Person
}
var jon Person -------> { 0 , "" , nil }
nil并不是关键字:
nil不是关键字(keyword):
比如:下面的语句可以通过编译,但是后续这个变量会隐藏空值nil的用法
var nil = errors.New("oh my god !!")
nil的意义:
1、当变量的类型为指针时,nil表示该指针不指向任何值,即不能从指针中取值
2、当变量的类型为切片时,nil表示该切片没有backing array),即切片的长度和容量都为0,
系统没有为该切片分配存储空间。
3、当变量的类型为映射/通道/函数时,nil表示该变量未初始化;
* 未初始化的映射只能读不能写
* 未初始化的通道只能读不能写,且读会造正阻塞
* 未初始化的函数不能被调用
4、当变量的类型为接口时,nil表示该变量没有值,也不能是一个空指针。
* 接口由两部分组成,一部分是类型,另一部分是值;
* 只有当类型和值都为nil时,该变量才等于nil。
nil的地址和值:
nil类型的所有值的内存布局始终相同,不同类型nil的内存地址是一样的
package main
import (
"fmt"
)
func main() {
var a map[string]string
var b *int
var c []int
fmt.Printf("%p\n", a) //0x0
fmt.Printf("%p\n", b ) //0x0
fmt.Printf("%p\n", c ) //0x0
}
nil值的大小始终与其类型与nil值相同的non-nil值大小相同。表示不同零值的nil标识符可能
具有不同的大小。
package main
import (
"fmt"
"unsafe"
)
func main() {
var p *struct{} = nil
fmt.Println( unsafe.Sizeof( p ) )
var s []int = nil
fmt.Println( unsafe.Sizeof( s ) )
nil值的比较:
1、不同类型的nil是不能比较的
2、同一类型的两个nil值可能无法比较 因为golang中存在map、slice和函数类型是不
可比较类型,它们有一个别称为不可比拟的类型,所以比较它们的nil亦是非法的
其它细节还有待细细品味!