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。

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接口。
- 2 回答
- 0 关注
- 199 浏览
添加回答
举报