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")
}
}
...

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")
}
}
}