这里有一些代码:
var v interface{}
v = (*string)(nil)
// Reflect says it is nil
val := reflect.ValueOf(v)
if val.IsNil() {
fmt.Println("val is nil")
} else {
fmt.Println("val is not nil")
}
// This says it is not nil
if v == nil {
fmt.Println("v is nil")
} else {
fmt.Println("v is not nil")
}
https://play.golang.org/p/apyPa4CNZ6
输出结果为:
val是零
v不是零
这怎么可能?是否为零?
另外,如果用
更改前两行v := (*string)(nil)
然后输出清楚地表明该变量为零。
现在,在我的项目中,我有一个接受类型为interface {}的参数的函数,我无法通过简单的v == nil来可靠地检查它是否为零。我想避免使用反射包。
答案 0 :(得分:3)
在封面下,接口实现为两个元素,一个类型 和一个价值。该值称为接口的动态值,是一个 任意具体值,类型是值的类型。为了 int value 3,接口值示意性地包含(int,3)。
仅当内部值和类型都是两者时,接口值才为nil 未设置,(无,无)。特别是,nil接口将始终保持 零类型。如果我们在接口中存储类型为* int的nil指针 值,内部类型将是* int,无论值是什么 指针:(* int,nil)。因此,这样的界面值将是 即使内部指针为零也不为零。
您可以尝试fmt.Printf("(%v, %T)\n", v, v)
。它会打印(<nil>, *string)
。
当您将前两行更改为v := (*string)(nil)
时,v
只是一个指针,而不是一个界面。