interface类型的错误判断
对于interface
类型的数据,建议不要通过简单的interface == nil
进行判断,否则会出现误判。
func main() {
var data *byte
var in interface{}
fmt.Println(data, data == nil) // nil,true, 可以正确判断
fmt.Println(in, in == nil) // nil,true, 可以正确判断
in = data
fmt.Println(in, in == nil) // nil,false, 无法正确判断
fmt.Println(in, reflect.ValueOf(in).IsNil()) // nil,true, 通过此方法可以正确判断interface类型nil值
}
即使该interface类型值确实为nil,但是通过==
是无法判断出来的,需要使用reflect.ValueOf
。
原理
interface类型并不是一个指针类型,它包含两类数据结构:
-
runtime.eface
结构体:表示不包含任何方法的空接口,也称为 empty interface -
runtime.iface
结构体:表示包含方法的接口
即一个interface包含了一个类型和一个值。使用==
判断interface是否为nil时,会同时判断类型和值是否均为nil,只有当类型和值均为nil的情况下,==才会判断为nil
在上文中,我们为指针赋值了一个零值的指针类型,导致类型不为空,进而导致==误判,所以此时需要reflect来进行正确的判断。