先上代碼:
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赖瞒,底層數(shù)據(jù)為int類型(類型T并非int的類型別名女揭,注意區(qū)分type T = int
),其同時(shí)實(shí)現(xiàn)了接口A和接口B。上面的代碼運(yùn)行時(shí)栏饮,結(jié)果如下:
T
T
T
T
但是我稍微改動一下switch...case的代碼后吧兔,結(jié)果發(fā)生了變化:
...
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袍嬉。這里可以得出一個(gè)結(jié)論境蔼,如果類型斷言時(shí),如果被斷言的數(shù)據(jù)同時(shí)符合多個(gè)case分支時(shí)伺通,只會命中第一個(gè)符合的case分支箍土。
原理解析:
通過匯編可以發(fā)現(xiàn),在執(zhí)行case 語句時(shí)會調(diào)用runtime.assertE2I2
函數(shù):
image.png
然后就是看源碼了罐监。吴藻。。
對源碼有興趣的話弓柱,可以移步這個(gè)視頻:https://www.bilibili.com/video/BV1hv411x7we?p=14