golang 中的 nil的场景分析
源码中的 nil 是这样定义的
// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
所以 nil 可以理解为这些类型的零值,声明一个变量在没有赋值的情况下,变量处于零值状态。
场景一
func t1() {
var i interface{}
var p *int
fmt.Println("p==i", p == i)
fmt.Println("i=", i, "i==null", i == nil)
fmt.Println("p=", p, "p==nil", p == nil)
fmt.Println("i TypeOf=", reflect.TypeOf(i), "i ValueOf", reflect.ValueOf(i))
fmt.Println("p TypeOf=", reflect.TypeOf(p), "p ValueOf", reflect.ValueOf(p))
i = p
fmt.Println("---")
fmt.Println("p==i", p == i)
fmt.Println("i=", i, "i==null", i == nil)
fmt.Println("p=", p, "p==nil", p == nil)
fmt.Println("i TypeOf=", reflect.TypeOf(i), "i ValueOf", reflect.ValueOf(i))
fmt.Println("p TypeOf=", reflect.TypeOf(p), "p ValueOf", reflect.ValueOf(p))
}
真相是 i 刚开始没有类型,而 p 是有类型,所以 p 和 i 都等于 nil,但是 == 可以理解为 php 或者 js 里面的 === 全等,既要类型相等,也要值相等。
在 i = p 之后,p 和 i 类型和值保持了一致所以会相等,但是 i 已经不等于 nil 了,因为 nil 是 interface 的 0 值,或者说 i 已经指向 p ,i 现在是个有类型状态而非 0 值状态。
结果如下
p==i false
i= <nil> i==null true
p= <nil> p==nil true
i TypeOf= <nil> i ValueOf <invalid reflect.Value>
p TypeOf= *int p ValueOf <nil>
---
p==i true
i= <nil> i==null false
p= <nil> p==nil true
i TypeOf= *int i ValueOf <nil>
p TypeOf= *int p ValueOf <nil>
场景二
func t3() {
f1 := func(i interface{}) bool {
return i == nil
}
var a *int
fmt.Println(f1(a)) // false
fmt.Println(f1(nil)) // true
}
a 传递到 func 里面,被转成 interface,这个 interface 是有类型的 interface,相当于赋值了一下 i=a ,所以 i 的状态不是 interface 的零值状态 ,和 interface 零值状态的 nil 当然是不相等
场景三
type A struct {
}
func (A) a1() int {
return 123
}
func (*A) a2() int {
return 321
}
type B interface {
}
func t2() {
var a A
var ap *A
var b B
var bp *B
fmt.Println("a=", a, "a.a1()", a.a1(), a.a2()) //a= {} a.a1() 123 321; a == nil 会抛错 struct 不能和 nil 进行比较
fmt.Println("ap=", ap, "ap==nil", ap == nil) //ap= <nil> ap==nil true
fmt.Println("b=", b, " b==nil:", b == nil) // b= <nil> b==nil: true
fmt.Println("bp=", bp, " bp==nil:", bp == nil) //bp= <nil> bp==nil: true
}
结构体的 0 值为 {}
到此这篇关于golang 中的 nil的场景分析的文章就介绍到这了,更多相关golang 中的 nil内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341