在golang中如何正确判断接口是否为nil
2021/12/16 6:10:07
本文主要是介绍在golang中如何正确判断接口是否为nil,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
本文主要来分析一下在golang中,如何判断interface是否为nil,以及相关注意事项。
正常情况下,我们声明一个interface类型的变量,默认值将会返回nil,以golang自带的io.Writer
为例
var writer io.Writer fmt.Printf("writer is nil => %t\n", writer == nil)
当然我们也可以用具体的实现结构来定义一个指针变量,它的默认值也是nil
var bufWriter *bufio.Writer fmt.Printf("bufWriter is nil => %t\n", bufWriter == nil)
输出结果与上述的一样
以上的输出都是我们预期中的结果。
在实际开发中我们经常会碰到从某个函数中返回interface实例的情况,例如
bufWriter := func() io.Writer { var w *bufio.Writer fmt.Printf("w is nil => %t\n", w == nil) return w }() fmt.Printf("bufWriter is nil => %t\n", bufWriter == nil)
此时我们的返回值是否仍旧与预期中的一致呢?
结果好像跟我们预想的有一些不太一样,因为在匿名函数中返回的是一个定义但是还未赋值的指针类型,并且在函数内部判断时,已经输出该变量为nil了,但是当我们在外部接收到这个值的时候,似乎变成非nil状态了
看着好像有一些诡异
那么,让我们来实际调用一下这个接口的函数试试
bufWriter := func() io.Writer { var w *bufio.Writer fmt.Printf("w is nil => %t\n", w == nil) return w }() if bufWriter != nil { bufWriter.Write([]byte("golang")) }
可以看到,我们明明已经进行非空判断了,结果还是panic了
这是怎么回事呢?
其实当我们使用==直接将一个interface与nil进行比较的时候,golang会对interface的类型和值分别进行判断。
如果两者都为nil,在与nil直接比较时才会返回true,否则直接返回false。所以上面代码中interface与nil进行比较时返回的是false,因为此时interface变量的值是nil,但是他的类型不是nil,已经有了明确的实现类型,即bufio.Writer
。因而当我们调用这个interface的函数成员时,就会直接panic。
所以在实际开发中,当interface类型的返回值已经明确为nil时,应该直接返回nil,而不是具体实现结构的未赋值空指针
bufWriter := func() io.Writer { var w *bufio.Writer if w == nil { return nil } return w }() if bufWriter != nil { bufWriter.Write([]byte("golang")) } else { fmt.Println("bufWriter is nil") }
可以看到,此时我们可以正确判断interface是否为nil了
那么有没有办法去判断interface的真实值是否为nil呢?
当然可以,答案就是使用反射,示例如下:
bufWriter := func() io.Writer { var w *bufio.Writer fmt.Printf("w is nil => %t\n", w == nil) return w }() fmt.Printf("bufWriter is nil => %t\n", bufWriter == nil) fmt.Printf("IsNil => bufWriter is nil => %t\n", reflect.ValueOf(bufWriter).IsNil())
可以看到,当我们通过反射来判断是否为nil时,获取到了与我们预期一样的结果
参考资料
Why is my nil error value not equal to nil?
这篇关于在golang中如何正确判断接口是否为nil的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-24MongoDB资料:新手入门完全指南
- 2024-12-20go-zero 框架的 RPC 服务 启动start和停止 底层是怎么实现的?-icode9专业技术文章分享
- 2024-12-19Go-Zero 框架的 RPC 服务启动和停止的基本机制和过程是怎么实现的?-icode9专业技术文章分享
- 2024-12-18怎么在golang中使用gRPC测试mock数据?-icode9专业技术文章分享
- 2024-12-15掌握PageRank算法核心!你离Google优化高手只差一步!
- 2024-12-15GORM 中的标签 gorm:"index"是什么?-icode9专业技术文章分享
- 2024-12-11怎么在 Go 语言中获取 Open vSwitch (OVS) 的桥接信息(Bridge)?-icode9专业技术文章分享
- 2024-12-11怎么用Go 语言的库来与 Open vSwitch 进行交互?-icode9专业技术文章分享
- 2024-12-11怎么在 go-zero 项目中发送阿里云短信?-icode9专业技术文章分享
- 2024-12-11怎么使用阿里云 Go SDK (alibaba-cloud-sdk-go) 发送短信?-icode9专业技术文章分享