关于 nil 的一些事情
关于 nil 的一些事情
本质
首先,nil 没有 type,并且,nil 也不是关键字 而是 预声明的标示符。
其次,在 Go 语言中有以下几种类型可以取值 nil:
类型
nil值含义
pointer
指向nothing, 比较时需要考虑类型是否一致
slice
slice变量中的3个成员值:buf为nil, len和cap都是0
interface
interface包含'type,value', 一个nil interface必须二者都为nil:'nil, nil'
map,channel,function
一个nil pointer,指向nothing
示例
接下来,我们来看一段代码,看看 go 语言中对 nil 判定的坑:
会发现两个问题: 1. t.PrintMsg() 可以执行 但是 t.PrintMsgV2() 会崩溃 2. 第二个判定竟然 err != nil 3. 第三个判断竟然 ip == nil
第一个问题
t.PrintMsg()
: 当我们用一个空指针类型的变量(如,var t *ErrNil)调用此方法时,该方法是会执行的,只有在执行该空指针变量的解指针操作(t.msg)时,才会 panic。
t.PrintMsgV2()
: 由于接受者是 ErrNil 而不是 ErrNil,使用指针访问该函数时,Golang 内部会在调用时自动解指针,故使用空指针类型的变量(如,var t ErrNil)调用此方法时会 panic。
关于第二个问题:
简单说,interface 被两个元素 value 和 type 所表示。只有在 value 和 type 同时为 nil 的时候,判断 interface == nil 才会为 true。具体可以参考官方文档
关于第三个问题:
这就涉及到 slice 的使用问题。
golang 中的类型可以是基本类型,如:int、float、bool、string;结构化的(复合的),如:struct、array、slice、map、channel;只描述类型的行为的,如:interface。
结构化的类型没有真正的值,它使用 nil 作为默认值。简单的说,[]interface{} 是一个指向 具体 slice 类型对象的指针。所以,可以用 nil 进行赋值 和 判断。
Last updated