美文网首页
golang 中的 nil

golang 中的 nil

作者: 追风骚年 | 来源:发表于2021-03-16 21:08 被阅读0次

源码中的 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

    源码中的 nil 是这样定义的 所以 nil 可以理解为这些类型的零值,声明一个变量在没有赋值的情况下,变量处于零...

  • golang中nil有趣转化

    nil 函数自动转化 函数形参:nil; 猜想测试 得出结论当调用函数时候,实参是nil,会自动转化成形式参数类型...

  • golang 不同类型的nil值

    golang 不同类型的nil值 nil通道 通道必须使用make函数进行初始化,对nil管道进行读写会导致永久阻...

  • 常见问题之Golang—— panic: assignment

    常见问题之Golang—— panic: assignment to entry in nil map 背景 知识...

  • golang err!=nil

    今天写代码的时候,发现一个和预期不符合的逻辑。简单描述就是把一个值为nil的A类型的error赋值给接口error...

  • golang中的nil与空接口

    而指针,函数,interface,slice,channel和map的零值都是nil可以看看下面代码的例子。 ni...

  • Golang 关于 nil 的认识

    Golang 关于 nil 的认识 1. 什么是 nil ? 大家都清楚,当你声明了一个变量 但却还并木优赋值时,...

  • 小口啃 Golang - 返回的 nil 不为 nil 的疑惑

    前段时间在写代码的时候,遇到一个奇怪的问题,即返回的 nil 值,不为 nil。 导致这个问题的原因是对 Go 中...

  • Golang使用Map的正确姿势

    初始化后再使用 Golang中,map是引用类型,如切片一样,通过下面的代码声明后指向的是nil,所以千万别直接声...

  • iOS中类和对象,nil/Nil/NULL的区别

    nil、Nil、NULL的区别 nil:指向oc中对象的空指针,针对对象。 Nil:指向oc中类的空指针,针对类。...

网友评论

      本文标题:golang 中的 nil

      本文链接:https://www.haomeiwen.com/subject/vahjcltx.html