Golang-如何判断一个 interface{} 的值是否为 nil

作者:Ch3n 时间:2024-02-17 10:08:10 

引用

起初我会下意识的回答,直接 v == nil 进行判断不就好了吗?
然后翻阅了很多资料终于大致搞定里面的道道.

例子

请看下面这段代码,可以先猜测一下输出的结果。

package main
import (
   "fmt"
)
func main()  {
   var a *string = nil
   var b interface{} = a
   fmt.Println(b==nil)
}

答案应该会跟你下意识的回答 相反

输出的结果的是 false

两个 interface 比较

interface 的内部实现包含了两个字段,一个是 type,一个是 data

对于这样一个变量
var age interface{} = 25

其实内部结构是

Golang-如何判断一个 interface{} 的值是否为 nil

因此两个 interface 比较,势必与这两个字段有所关系。

经过验证,只有下面两种情况,两个 interface 才会相等。

第一种情况

typedata 都相等

看以下代码例子:

package main
import "fmt"
type Profile struct {
   Name string
}
type ProfileInt interface {}
func main()  {
   var p1, p2 ProfileInt = Profile{"iswbm"}, Profile{"iswbm"}
   var p3, p4 ProfileInt = &Profile{"iswbm"}, &Profile{"iswbm"}
   fmt.Printf("p1 --> type: %T, data: %v \n", p1, p1)
   fmt.Printf("p2 --> type: %T, data: %v \n", p2, p2)
   fmt.Println(p1 == p2)  // true
   fmt.Printf("p3 --> type: %T, data: %p \n", p3, p3)
   fmt.Printf("p4 --> type: %T, data: %p \n", p4, p4)
   fmt.Println(p3 == p4)  // false
}

运行后,输出如下

p1 --> type: main.Profile, data: {iswbm} 
p2 --> type: main.Profile, data: {iswbm} 
true
p3 --> type: *main.Profile, data: 0xc00008e200 
p4 --> type: *main.Profile, data: 0xc00008e210 
false

  • 在代码中,p1p2type 都是 Profiledata 都是 {"iswbm"},因此 p1p2 相等

  • p3p4 虽然类型都是 *Profile,但由于 data 存储的是结构体的地址,而两个地址和不相同,因此 p3 p4 不相等

第二种情况

特殊情况:两个 interface 都是 nil

当一个 interface 的 type 和 data 都处于 unset 状态的时候,那么该 interface 的类型和值都为 nil

package main
import "fmt"
func main() {
   var p1, p2 interface{}
   fmt.Println(p1 == p2)  // true
   fmt.Println(p1 == nil) // true
}

interface 与 非 interface 比较

当 interface 与非 interface 比较时,会将 非interface 转换成 interface ,然后再按照 两个 interface 比较 的规则进行比较。

示例代码:

package main
import (
   "fmt"
   "reflect"
)
func main()  {
   var a string = "iswbm"
   var b interface{} = "iswbm"
   fmt.Println(a==b) // true
}

上面这种例子可能还好理解, atype string, valueiswbm , btype string, valueiswbm ,所以打印为true

那么请你看下面这个例子(文章开头的示例),为什么 b 与 nil 不相等?

package main
import (
   "fmt"
)
func main()  {
   var a *string = nil
   var b interface{} = a
   fmt.Println(b==nil) // false
}

但当你使用 b==nil 进行判断时,其实右边的 nil 并非单纯的是我们所理解的值为nil,而正确的理解应该是 type 为 nil 且 value 也为 nil。

Go 会先将 nil 转换为interface (type=nil, data=nil) ,这与 b (type=*string, data=nil) 虽然 data 是一样的,但 type 不相等,因此他们并不相等

那有没有办法判断一个 interface{} 是不是 nil 呢?

有办法的,但是要借助反射,一个非万不得已不会使用的 reflect 包。

package main
import (
   "fmt"
   "reflect"
)
func IsNil(i interface{}) bool {
   vi := reflect.ValueOf(i)
   if vi.Kind() == reflect.Ptr {
       return vi.IsNil()
   }
   return false
}
func main() {
   var a *string = nil
   var b interface{} = a
   fmt.Println(IsNil(b))
}

参考资料

如何判断一个 interface{} 的值是否为 nil ?
彻底理解golang中什么是nil

来源:https://blog.csdn.net/weixin_43064185/article/details/130602580

标签:Golang,interface{},nil
0
投稿

猜你喜欢

  • python实现会员信息管理系统(List)

    2021-12-21 04:50:45
  • 将tensorflow模型打包成PB文件及PB文件读取方式

    2022-07-02 22:47:33
  • Python中tkinter+MySQL实现增删改查

    2024-01-20 06:49:59
  • java数据库开发之JDBC基础使用方法及实例详解

    2024-01-21 04:37:00
  • python jinja2模板的使用示例

    2023-08-11 05:12:12
  • ASP中如何判断一个字符是不是汉字

    2008-05-04 12:47:00
  • linux环境下python中MySQLdb模块的安装方法

    2024-01-26 23:17:27
  • 用ASP判断客户端浏览器语言自动跳转

    2010-07-09 13:34:00
  • mysql 常用命令集锦(Linux/Windows)

    2024-01-17 07:26:20
  • 一文带你了解Go语言实现的并发神库conc

    2024-05-13 10:43:22
  • 利用Python制作一个MOOC公开课下载器

    2022-03-13 19:46:17
  • python正则表达式常见的知识点汇总

    2023-10-02 18:56:21
  • pd.read_csv读取文件路径出现的问题解决

    2022-03-16 06:12:53
  • python_opencv用线段画封闭矩形的实例

    2022-05-04 19:07:59
  • 一文轻松掌握python语言命名规范规则

    2023-03-23 02:11:43
  • Django视图、传参和forms验证操作

    2023-03-04 09:17:03
  • JS+CSS实现闪烁字体效果代码

    2024-04-18 09:31:04
  • 向外扩展SQL Server 实现更高扩展性

    2008-12-18 14:45:00
  • Python+xlwings制作天气预报表

    2021-03-26 14:08:31
  • python条件变量之生产者与消费者操作实例分析

    2023-05-06 02:06:42
  • asp之家 网络编程 m.aspxhome.com