先上代码:
package main
import (
"fmt"
)
type A interface {
FuncA()
}
type B interface {
FuncB()
}
type T int
func (t T) FuncB() {}
func (t T) FuncA() {}
func main() {
var v T
fmt.Println(typeOf(v))
fmt.Println(typeOf(A(v)))
fmt.Println(typeOf(B(v)))
var a A = v
var b A = v
fmt.Println(typeOf(a))
fmt.Println(typeOf(b))
}
func typeOf(v interface{}) string {
switch v.(type) {
case T:
return "T"
case A:
return "A"
case B:
return "B"
default:
return "unknown"
}
}
类型T,底层数据为int类型(类型T并非int的类型别名,注意区分type T = int
),其同时实现了接口A和接口B。上面的代码运行时,结果如下:
T
T
T
T
但是我稍微改动一下switch...case的代码后,结果发生了变化:
...
switch v.(type) {
// case T:
// return "T"
case A:
return "A"
case B:
return "B"
default:
return "unknown"
}
...
// output:
A
A
A
A
同理如果注释掉case A代码段后,输出的都是B。这里可以得出一个结论,如果类型断言时,如果被断言的数据同时符合多个case分支时,只会命中第一个符合的case分支。
原理解析:
通过汇编可以发现,在执行case 语句时会调用runtime.assertE2I2
函数:
然后就是看源码了。。。
对源码有兴趣的话,可以移步这个视频:https://www.bilibili.com/video/BV1hv411x7we?p=14
网友评论