很久之前发过一篇文章:《10个令人惊叹的Go语言技巧,让你的代码更加优雅》,这篇文章中第八点有一处错误的地方被认真的读者发现了:
图片
于是我有空之后,立马重新看了那篇文章的内容,确实是存在读者所说的问题。
问题就在于下面这句话,文章也是有列出的:
即使接口持有的值为 nil,也不意味着接口本身为 nil。
但是在执行以下语句的时候,是有可能报 panic 的:
return reflect.ValueOf(x).IsNil()
而输出也是非常明显的指出错误:
panic: reflect: call of reflect.Value.IsNil on int Value
因为不可 nil 的 interface 是不能使用 reflect.Value.IsNil 方法。
那么问题就很好解决了。
我们在执行 reflect.Value.IsNil 方法之前,进行一次判断是否为指针即可:
func IsNil(x interface{}) bool { if x == nil { return true } rv := reflect.ValueOf(x) return rv.Kind() == reflect.Ptr && rv.IsNil()}
重点在于 rv.Kind() == reflect.Ptr && rv.IsNil() 这段代码。
这段代码的作用:
下面我们使用几种常见的数据类型来进行测试:
func IsNil(x interface{}) bool { if x == nil { return true } rv := reflect.ValueOf(x) return rv.Kind() == reflect.Ptr && rv.IsNil()}func main() { fmt.Printf("int IsNil: %t/n", IsNil(returnInt())) fmt.Printf("intPtr IsNil: %t/n", IsNil(returnIntPtr())) fmt.Printf("slice IsNil: %t/n", IsNil(returnSlice())) fmt.Printf("map IsNil: %t/n", IsNil(returnMap())) fmt.Printf("interface IsNil: %t/n", IsNil(returnInterface())) fmt.Printf("structPtr IsNil: %t/n", IsNil(returnStructPtr()))}func returnInt() interface{} { var value int return value}func returnIntPtr() interface{} { var value *int return value}func returnSlice() interface{} { var value []string return value}func returnMap() interface{} { var value map[string]struct{} return value}func returnInterface() interface{} { var value interface{} return value}type People struct { Name string}func returnStructPtr() interface{} { var value *People return value}
我们先后使用了 int、*int、slice、map、interface{}、自定义结构体 来测试此 IsNil 方法。运行程序输出为:
int IsNil: falseintPtr IsNil: trueslice IsNil: falsemap IsNil: falseinterface IsNil: truestructPtr IsNil: true
从测试结果来看,目前是符合我们对此方法的定位的。
本文链接:http://www.28at.com/showinfo-26-60935-0.html我们优雅判断 interface 是否为 nil
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 如何在函数式编程中处理可变状态和副作用?
下一篇: 麻了,这让人绝望的大事务提交