为了账号安全,请及时绑定邮箱和手机立即绑定

识别存储在 go 接口中的实际类型

识别存储在 go 接口中的实际类型

Go
德玛西亚99 2022-07-11 15:54:41
在下面的代码中    var r io.Reader    c, _ := net.Dial("tcp", ":8080")    r = c     switch r.(type) {    case io.Reader:        fmt.Println("r implements the reader interface")        // fallthrough    case io.Writer:        fmt.Println("r implements the writer interface")    case net.Conn:        fmt.Println("r implements the conn interface")    }第一个case语句是始终执行的语句。如果我取消注释fallthrough代码将无法编译,因为fallthrough类型开关中不允许这样做如果我没记错,go接口有 2 个值:存储在接口中的实际类型(描述符)(例如io.Writer,io.Reader等)存储在其中的值既然r显然满足上述所有case陈述,那么找到存储在中的确切类型的方法是什么r?是不是只能通过反射才能完成这个锥体?
查看完整描述

2 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

类型切换和类型断言可用于检查接口值是否包含具体类型的值(同时提取该具体类型的值)。如果您检查的类型(或断言类型)是接口类型(而不是具体类型),则如果具体类型实现给定的接口类型,则大小写将匹配(或断言将成立)。


net.Conn是一个接口,它是io.Reader和的超集io.Writer。如果某物 implements net.Conn,它也会自动实现io.Readerand io.Writer,所以如果你先检查io.Reader,那将匹配(如果类型也 implements net.Conn)。


如果您想使用类型开关检查已实现的接口,请先检查net.Conn,如果未实现,请列出io.Reader并io.Writer稍后。


switch r.(type) {

case net.Conn:

    fmt.Println("r implements the conn interface")

case io.Reader:

    fmt.Println("r implements the reader interface")

case io.Writer:

    fmt.Println("r implements the writer interface")

}

如果我没记错的话,go 接口有 2 个值:


存储在接口中的实际类型(描述符)(例如 io.Writer、io.Reader 等)

存储在其中的值

你没有错,但你错过了一个关键点:实际的具体类型。io.Conn并且io.Reader不是具体类型,它们是接口类型。


可能返回的示例具体net.Dial()类型是*net.TCPConn。


查看完整回答
反对 回复 2022-07-11
?
FFIVE

TA贡献1797条经验 获得超6个赞

使用此代码查找值的具体类型:


var r io.Reader

c, _ := net.Dial("tcp", ":8080")

r = c 

fmt.Printf("The type of r is %T\n", r)

reflect 包也可用于查找具体类型:


t := reflect.TypeOf(r)

fmt.Println("The type of or is", t)

使用单独的 if 语句来检查对每个接口的支持。类型开关无法测试所有接口,因为该开关继续使用第一个匹配的类型。


if _, ok := r.(io.Reader); ok {

    // we know this already because r is an io.Reader

    fmt.Println("r implements the reader interface")

}

if _, ok := r.(io.Writer); ok {

    fmt.Println("r implements the writer interface")

}

if _. ok := r.(net.Conn); ok {

    fmt.Println("r implements the conn interface")

}

我们知道所有 if 语句中的条件都为 true,因为 in 的值r满足net.Conn接口。


查看完整回答
反对 回复 2022-07-11
  • 2 回答
  • 0 关注
  • 199 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号