如何v == nil返回false并反映.ValueOf(v).IsNil()同时返回true?

时间:2017-02-14 04:23:18

标签: go

这里有一些代码:

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来可靠地检查它是否为零。我想避免使用反射包。

1 个答案:

答案 0 :(得分:3)

From golang.org

  

在封面下,接口实现为两个元素,一个类型   和一个价值。该值称为接口的动态值,是一个   任意具体值,类型是值的类型。为了   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只是一个指针,而不是一个界面。