go 学习 5 接口

接口类型 interface 是由一组方法签名定义的集合。

接口类型的值可以保存任何实现了这些方法的值。

在内部,接口值可以看做包含值和具体类型的元组:(value, type)

type I interface {
    M()
}

type T struct {
    S string
}

func (t *T) M() {
    fmt.Println(t.S)
}

type F float64

func (f F) M() {
    fmt.Println(f)
}

func main() {
    var i I

    i = &T{"Hello"}
    describe(i)
    i.M()

    i = F(math.Pi)
    describe(i)
    i.M()
}

指定了零个方法的接口值被称为 空接口:interface{}

空接口被用来处理未知类型的值。

func main() {
    var i interface{}
    describe(i)

    i = 42
    describe(i)

    i = "hello"
    describe(i)
}

func describe(i interface{}) {
    fmt.Printf("(%v, %T) ", i, i)
}

类型断言 提供了访问接口值底层具体值的方式。

t := i.(T) 该语句断言接口值 i 保存了具体类型 T ,并将其底层类型为 T 的值赋予变量 t 。若 i 并未保存 T 类型的值,该语句就会触发一个恐慌。

为了 判断 一个接口值是否保存了一个特定的类型, 类型断言可返回两个值:其底层值以及一个报告断言是否成功的布尔值。

t, ok := i.(T)若 i 保存了一个 T ,那么 t 将会是其底层值,而 oktrue 。否则, ok 将为 falset 将为 T 类型的零值,程序并不会产生恐慌。

类型选择 是一种按顺序从几个类型断言中选择分支的结构。
func do(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("Twice %v is %v ", v, v*2)
    case string:
        fmt.Printf("%q is %v bytes long ", v, len(v))
    default:
        fmt.Printf("I don't know about type %T! ", v)
    }
}
原文地址:https://www.cnblogs.com/arwen-spy/p/6505876.html