Golang进阶

实现多个接口的类型,在类型断言时的行为

2021-12-09  本文已影响0人  qishuai

先上代码:

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函数:

image.png
然后就是看源码了。。。
对源码有兴趣的话,可以移步这个视频:https://www.bilibili.com/video/BV1hv411x7we?p=14
上一篇 下一篇

猜你喜欢

热点阅读