golang类型断言理解[go语言圣经]

类型断言

个人理解

这个东西看了好久才看懂,然后还借鉴了一下其他的文章: Go 语言中的类型断言是什么?

虽然这个借鉴的文章没有讲全,讲透,但是让我理解go语言圣经里面写的内容起到了帮助

我的理解关键点是:
首先,x.(T), x必然是一个接口,接口有3个属性

  1. 接口动态类型
  2. 接口的动态值
  3. 接口的方法集合

具体类型的属性

  1. 类型
  2. 存储的对应类型的值
  3. 方法(可能没有方法,和类型共同决定满足哪些接口)
Go 语言数据类型包含基础类型和复合类型两大类。
基础数据类型包括:布尔型、整型、浮点型、复数型、字符型、字符串型、错误类型。
复合数据类型包括:指针、数组、切片、字典、通道、结构体、接口。

T取值:

  1. 然后T可以是具体的类型,判断是否x是否是这个类型,如果是,则把类型断言的结果是x的动态值(接口的属性),它的类型是T(具体类型的属性)
  2. 如果T是接口类型,则类型断言结果的接口的类型和接口动态值还是不变,值变化接口的方法集合(通过更大)—可以看后面的一小点小测试

x取值:

如果为nil,会panic,当然类型断言如果用了 _, ok = x.(T) 则会ok = false

var k io.Writer
_, ok := k.(io.ByteReader)
fmt.Println(k)
fmt.Println(ok)
// <nil>
// false
go语言圣经原文以及一小点测试

类型断言是一个使用在接口值上的操作。语法上它看起来像x.(T)被称为断言类型,这里x表示一个接口的类型和T表示一个类型。一个类型断言检查它操作对象的动态类型是否和断言的类型匹配。

这里有两种可能。第一种,如果断言的类型T是一个具体类型,然后类型断言检查x的动态类型是否和T相同。如果这个检查成功了,类型断言的结果是x的动态值,当然它的类型是T。换句话说,具体类型的类型断言从它的操作对象中获得具体的值。如果检查失败,接下来这个操作会抛出panic。例如:

var w io.Writer
w = os.Stdout
f := w.(*os.File)      // success: f == os.Stdout
c := w.(*bytes.Buffer) // panic: interface holds *os.File, not *bytes.Buffer

第二种,如果相反地断言的类型T是一个接口类型,然后类型断言检查是否x的动态类型满足T。如果这个检查成功了,动态值没有获取到;这个结果仍然是一个有相同动态类型和值部分的接口值,但是结果为类型T。换句话说,对一个接口类型的类型断言改变了类型的表述方式,改变了可以获取的方法集合(通常更大),但是它保留了接口值内部的动态类型和值的部分。

在下面的第一个类型断言后,w和rw都持有os.Stdout,因此它们都有一个动态类型*os.File,但是变量w是一个io.Writer类型,只对外公开了文件的Write方法,而rw变量还公开了它的Read方法。

var w io.Writer
w = os.Stdout
fmt.Printf("%v %T\n", w, w)
rw := w.(io.ReadWriter) // success: *os.File has both Read and Write
fmt.Printf("%v %T\n", w, w)
fmt.Printf("%v %T\n", rw, rw)
w = new(ByteCounter)
rw = w.(io.ReadWriter) // panic: *ByteCounter has no Read method
 ⚡ 06/10|10:26:33  test  go run str.go
&{0xc0000780c0} *os.File
&{0xc0000780c0} *os.File
&{0xc0000780c0} *os.File
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值