Go 优雅判断 interface 是否为 nil

TimLiuDream · · 906 次点击 · 开始浏览    置顶

> 关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力! ## 背景 很久之前发过一篇文章:《[10个令人惊叹的Go语言技巧,让你的代码更加优雅](https://mp.weixin.qq.com/s/VOrh6zYR1C25sZgCj2lWvw)》,这篇文章中第八点有一处错误的地方被认真的读者发现了: ![Snipaste_2024-01-15_00-22-06.png](https://static.golangjob.cn/240115/6965139d87032259f89d66aa43220b8a.png) 于是我有空之后,立马重新看了那篇文章的内容,确实是存在读者所说的问题。 ## 问题 问题就在于下面这句话,文章也是有列出的: > 即使接口持有的值为 `nil`,也不意味着接口本身为 `nil`。 > 但是在执行以下语句的时候,是有可能报 `panic` 的: ```go return reflect.ValueOf(x).IsNil() ``` 而输出也是非常明显的指出错误: ```go panic: reflect: call of reflect.Value.IsNil on int Value ``` 因为不可 `nil` 的 `interface` 是不能使用 `reflect.Value.IsNil` 方法。 那么问题就很好解决了。 ## 解决方式 我们在执行 `reflect.Value.IsNil` 方法之前,进行一次判断是否为指针即可: ```go 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()` 这段代码。 这段代码的作用: - 判断 `x` 的类型是否为指针。 - 判断 `x` 的值是否真的为 `nil`。 下面我们使用几种常见的数据类型来进行测试: ```go 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` 方法。运行程序输出为: ```go int IsNil: false intPtr IsNil: true slice IsNil: false map IsNil: false interface IsNil: true structPtr IsNil: true ``` 从测试结果来看,目前是符合我们对此方法的定位的。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

906 次点击  ∙  2 赞  
加入收藏 微博
4 回复  |  直到 2024-02-06 20:04:54
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传