interface空指针不为nil
当把一个空指针对象赋值给一个interface后,
var pi *int = nil
var i interface{}
i = pi
fmt.Println(i == nil) // 结果为 false
这个不难理解,因为i = pi
,不是将nil賳值给i,而是让i指向了pi这个对象。
简单翻了下源码,interface的定义应该是下面这两中的一个。
type iface struct {
tab *itab
data unsafe.Pointer
}
type eface struct {
_type *_type
data unsafe.Pointer
}
i = pi
其实相当于i.data = unsafe.Pointer(&pi)
,而i == nil
相当于i.data == nil
。
判断interface里的指针是否为空
那么,现在的问题是,如何判断interface里的指针是否为空呢?
知道类型的情况下,自然是可以使用类型断言后判空。如
ai, ok := i.(*int)
,之后判断ai == nil
。不知道是何种类型的指针,就只好借助反射了
vi := reflect.ValueOf(i)
,后使用vi.IsNil()
来判断。但如果i里放到不是一个指针,调用IsNil会出异常,则可能要写一个这样的函数来判空
func IsNil(i interface{}) bool {
defer func() {
recover()
}()
vi := reflect.ValueOf(i)
return vi.IsNil()
}
但有这样强加一个defer的recover确实不好看,于是借助类型判断变成这样
func IsNil(i interface{}) bool {
vi := reflect.ValueOf(i)
if vi.Kind() == reflect.Ptr {
return vi.IsNil()
}
return false
}
有疑问加站长微信联系(非本文作者)