go中的类型断言

go中的类型断言共有四种
在这里插入图片描述
我们知道接口可以分为空接口和非空接口两类,相对于接口这种抽象类型,int,string,slice等等,都可以被称为具体类型
断言:判断一个变量是某种类型,是否可以转换为某种类型
类型断言作用在接口值之上(一般检验的是实现了该接口的动态变量),可以是空接口,也可以是非空接口。而断言的目标类型,可以是具体类型,也可以是非空接口类型。这样就组合出了四种类型断言,接下来我们就逐一看看,它们究竟是怎样断言的。

空接口.(具体类型)

在这里插入图片描述
在这个例子中,f是一个File变量,赋值给了e,此时e对应的动态变量就是f,静态变量依旧是空接口,如何此时检查e是否为File对象类型,只需要查看e中的_type类型是否为File类型即可,Go语言里每种类型的类型元数据都是全局唯一的,如果像这样给e赋值,e的动态之就是f,动态类型就是os.File,所以断言成功,ok为true,r被赋值为e的动态值f。

非空接口.(具体类型)

在这里插入图片描述
这里rw是非空接口,这句话也就是判断File是否实现了这个非空接口,如果实现了,则返回File到r中,如果不是则都返回nil。
具体怎么判断呢,rw接口中有一个itab指针,指向了关于具体数据类型的一些信息,rw.(os.File)是要判断rw的动态类型是否为os.File,这里的类型断言只需要一次比较就能完成。只要看它是否指向这个itab结构体就好。

空接口.(非空接口)

在这里插入图片描述
e.(io.ReadWriter)是要判断e的动态类型,是否实现了io.ReadWriter接口
由图可知,e的动态类型为f,os.File类型,其中的元数据数组实现了readwriter,所以返回true,如果e像这样赋值,它的动态之就是f,动态类型就是os.File,虽然os.File类型数据后面可以找到类型关联的方法元数据数组,也不必每次都去检查这里是否有对应接口要求的所有方法

在这里插入图片描述
不是有itab缓存嘛,可以先去itab缓存中查找一下,如果没有io.ReadWrite和os.File对应的itab结构体,那么就去检查os.File的方法列表。值得强调的是,就算能从缓存中查找到对应的itab指针,也要进一步判断itab.fun[0]是否等于0,这是因为断言失败的类型组合,其对应的itab结构体也会被缓存起来,只是会把itab.fun[0]置为0,用以标识这里的动态类型并没有实现对应的接口,这样以后在遇到同样类型断言时,就不用再去检查方法列表了,可以直接断言失败

非空接口.(非空接口)

在这里插入图片描述
w.(io.ReadWriter)是要判断w存储的动态类型是否实现了io.ReadWriter接口,w是io.Writer类型,接口要求一个Write方法,io.ReadWriter接口要求实现Read和Write两个方法。
在这里插入图片描述
找到w的动态类型为*os.File,其中实现了ReadWriter接口的方法,那么返回ok=true,以及rw
如果w像这样赋值,其动态值就是f,tab指向这样一个itab结构体。要确定os.File是否实现了io.ReadWriter接口,同样会先去itab缓存里查找这个组合对应的itab指针,若存在,且itab.fun[0]!=0,则断言成功,若不存在,再次检查os.File的方法列表,并缓存itab信息,这里断言成功,ok为true,rw为io.ReadWriter类型的变量,动态值与w相同。

该文章参考:https://juejin.cn/post/7133876992344064014#heading-8

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值