Go 是 nil 却 !=nil

Golang 225 字
package main

import "fmt"

func main() {
    var f func()

    var a *struct{}

    list := []interface{}{f, a}

    for _, item := range list {
        if item == nil {
            fmt.Println("nil")
        }
    }
}

我们来看上面的代码,我们的第一反应应该是输出两个 nil,但事实上并非如此。我们来在 for 循环中输出 item。

    ...
    for _, item := range list {
    fmt.Println(item)
        if item == nil {
            fmt.Println("nil")
        }
    }
    ...

 title=

item 的两个输出的确是 nil ,因为我们只是定义了两个变量却没有对变量进行复制,所以他的值肯定就是 nil,但是为什么在判断的时候确认为他们不是 nil 呢?

首先,我们要知道 fmt.Println 打印数据的时候是打印出变量的值,也就是相当于 fmt.Printlf("%v\n" ,item) ,但是 item 其实是有类型的,我们先修改一下代码。

package main

import "fmt"

func main() {
    //var f func()

    var a *struct{}

    list := []*struct{}{a}

    for _, item := range list {
        if item == nil {
            fmt.Println("nil")
        }
    }
}

//output: nil

当我们将 list 的类型修改为 []*struct{} 的时候就可以正确判断了,那么就说明是由于 interface 导致的判断出错。

我们在对 interface 进行 != nil 判断的时候,必须值和类型都为 nil 的时候才可以,我们可以通过 reflect 反射包来判断 一个 interface 的值是否为 nil.

package main

import (
    "fmt"
    "reflect"
)

func main() {
    //var f func()

    var a *struct{}

    list := []*struct{}{a}

    for _, item := range list {
        if  reflect.ValueOf(item).IsNil() {
            fmt.Println("nil")
        }
    }
}
maksim
Maksim(一笑,吡罗),PHPer,Goper
OωO
开启隐私评论,您的评论仅作者和评论双方可见