[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
相关文章
- 一个故事看懂Linux文件权限管理
- 闯荡Linux帝国:nginx的创业故事
- 实践GoF的设计模式:单例模式
- Go 1.18 新特性:多模块工作区模式
- 用过 mongodb 吧, 这三个大坑踩过吗?
- 教你配置windows上的windbg,linux上的lldb,打入clr内部这一篇就够了
- 使用mongodb作为Quartz.Net下的JobStore实现底层的持久化机制
- mongodb之使用explain和hint性能分析和优化
- mongodb 3.x 之实用新功能窥看[2] ——使用$lookup做多表关联处理
- mongodb 3.x 之实用新功能窥看[1] ——使用TTLIndex做Cache处理
- 双十一来了,别让你的mongodb宕机了
- 分享几个你可能不知道的交互式Git 命令
- 实践GoF的23的设计模式:SOLID原则(下)
- 实践GoF的23种设计模式:SOLID原则(上)
- k8s源码Client-go中Reflector解析
- HTTP流量神器Goreplay核心源码详解
- 手把手带你基于嵌入式Linux移植samba服务
- 8天学通MongoDB——第八天 驱动实践
- 8天学通MongoDB——第七天 运维技术
- 8天学通MongoDB——第六天 分片技术