谨慎对待Go语言中对interface的nil判断

谨慎对待Go语言中对interface的nil判断

在进行Go语言编程中,我们会看见诸如if err == nil {}或者if err != nil {}之类的判断,这跟go语言的错误处理哲学(计划失败而非成功 / 及早失败)有关;
大多数情况下,我们对一个err是否是nil进行判断是很直白的,无需考虑很多,但是如果对于interface的情况来说,处理的时候稍有点难度,多了许多要留意的地方。

看个重要的例子

package main

import (
	"bytes"
	"fmt"
	"io"
)

//check的参数类型是io.Writer,是一个interface,所以只要某个类型的变量具有了Write方法
//也就等同于实现了Writer这个接口
//Writer的源码定义如下
//type Writer interface {
//	Write(p []byte) (n int, err error)
//}
func check(w io.Writer) {
	if w != nil {
		fmt.Println("w不是nil")
	}
	fmt.Printf("w是 %+v\n",w)
}

func main() {
	var b *bytes.Buffer //默认值是nil
	//bytes包里面的Buffer是一个struct,它具有Write方法,也就实现了io.Writer接口
	//从而可以作为参数
	//func (b *Buffer) Write(p []byte) (n int, err error)
	check(b)
	 
	fmt.Printf("b的值是%+v\n",b)
}

大家可以先猜一下输出结果是什么?

.
.
.
.
.
.

w不是nil
w是 <nil>
b的值是<nil>

不知道你猜对了没?但是对于新手来说,这一点确实有点困惑,w怎么一会儿是nil,一会儿又不是呢?
其实这个奇怪的现象跟go语言中interface的内部结构有关, interface内部由一个类型T和一个值V构成,其中V是一个具体类型(int, struct, pointer,string…)的值,比如int类型的10或者string类型的“wdy”

PS: 前天我发了一篇名为《如何理解Go语言的空接口interface{}》,对interface内部不懂的同学请看回头翻一下那篇文章

重点来了

一个interface要想为nil,只有可能是它内部的 T 和 V 都为nil.

阅读下面代码的前提【知识储备-源码】

//我们知道error是一个类型,同时在go语言的源码定义中,error也是一个interface
type error interface {
    Error() string
}
//所以任意一个类型拥有了方法 func (any <any Type>) Error() string {}就是实现了error这个interface
//比如:
type some struct{}

func (s *some) Error() string {
    return "some"
}
//这个代码段说明*some这个类型实现了error这个interface
package main

import(
	"fmt"
)
type someError struct{} //类型定义

//*someError这个类型通过定义Error()函数实现了error这个接口
func (se *someError) Error() string {
	return "wdy"
}

func check(e error) {
	if e != nil {
		fmt.Println("e 不是nil")
	}else{
		fmt.Println("e 是 nil")
	}
	fmt.Printf("e的值是%+v\n",e)
}

func main() {
	//情况1
	var e error = nil
	check(e)
	
	fmt.Println()
	
	//情况2
	var se *someError = nil
	check(se)
}

同样请猜一下输出结果:

.
.
.
.
.
.

e 是 nil
e的值是<nil>

e 不是nil
e的值是wdy

记得实操一遍哦,自己在Go playground上面动手,尝试自己写一个例子。
【weixin-公-众-号:go学习】

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值