[Go]go语言中的零值

go语言中的零值是变量没有做初始化时系统默认设置的值

var b bool // bool型零值是false
var s string // string的零值是""

以下六种类型零值常量都是nil
var a *int
var a []int
var a map[string] int
var a chan int
var a func(string) int
var a error // error是接口
所有其他数值型的类型(包括complex64/128)零值都是0,可以用常量表达式代表数值0的任何形式表示出来。对于以上各种类型都可以通过==条件判断是不是零值.

1.string的零值是"",也可以用len(x)==0 来判断零值字符串。但是用""更好一点,把len(x)==0留给slice用。
2.数组和结构类似,有零值,但是没有相应的零值常量。
3.slice是个系统定义的结构,有三个字段:一个指针指到数据存储区,长度,存储区容量。只有三个字段都是零值的时候,这个变量才是零值。比如make([]int, 0, 0)创建的slice长度和容量都是0,但是指针不为空,所以不是零值。而且也没有办法直接设置slice所指向的指针,所以make出来的都不是零值。但是通常判断slice是不是空的时候是用len(x)==0,而不是用nil。用nil做判断容易混淆。如果函数返回值既可以是nil也可以是零长slice,那通常是不好的设计,但是调用者可以用len(x)==0做判断来避免问题。貌似go应该也可以设计成slice没有零值常量,只用len(x)==0来判断零长数组。这相当于一个结构没有零值常量,但是用一个方法来判断是不是初始化过了。

4.结构也有零值。
如果所有(递归的)字段都是零值,那么整个结构就是零值。但是没有零值常量用来表示某个结构的零值,所以也就无法用判断语句来识别一个结构是否处于零值。而且零值状态的结构也没有一个通用的语义,处于零值状态的结构可能意味着没有初始化,也可能是一个正常有用的状态。比如sync.Mutex零值状态就是处于没有锁住状态,是有意义的。所以不需要结构的零值常量。

5.接口也是个系统定义的结构,有两个字段,都是指针。一个指向实现该接口的具体类型的数据,一个指向实现该接口的具体类型的类型信息。两个字段都是nil的时候,这个变量才是nil。有一种情况是指向数据的指针是nil,指向类型的指针不是nil,这相当于this指针是空指针。此时在方法中访问数据的时候会segment fault,但是这种情况无法通过判断接口是nil识别出来。正常程序不应该出现这种只有数据是nil的情况。

6.零值的map也有一定功能,可以调用查询,但是无法赋值数据。可以用于描述一个只读的空集。
var m map[string]int
a, ok := m["xxx"] // 任何nil值的map对于任何key,查到的结果是value的类型的零值,ok是false。

7.零值的chan也有用,发送数据到nil chan或者从nil chan接收数据都会造成死等,而close时会发生panic

posted @ 2020-06-02 12:59  唯一客服系统开发笔记  阅读(768)  评论(0编辑  收藏  举报