Go的学习路程:接口(二)|Go 主题月

179 阅读2分钟

上一篇学习了接口的定义以及如何实现一个接口。接下来继续学习接口的相关知识。

空接口

空接口表示没有任何约束,因此任何类型变量都可以实现空接口。

用空接口可以表示任何数据类型。

package main

import "fmt"

// 空接口
type AllType interface {

}

func main () {
    var at AllType
    str := "hello world"
	// 将 string 类型变量 str 赋值给 AllType 类型变量 at,但是该变量实际引用的依然是 string 类型的实例
    at = str
    fmt.Printf("value:%v type:%T\n", at, at) // value:hello world type:string

    num := 32
	// 将 int 类型变量 num 赋值给 AllType 类型变量 at,但是该变量实际引用的依然是 int 类型的值
    at = num
    fmt.Printf("value:%v type:%T\n", at, at) // value:32 type:int

    flag := true
	// 将 bool 类型变量 flag 赋值给 AllType 类型变量 at,但是该变量实际引用的依然是 bool 类型的值
    at = flag
    fmt.Printf("value:%v type:%T", at, at) // value:true type:bool 
}

如上代码展示了,任何类型的变量都可以给空接口类型的变量赋值。虽然空接口类型的变量可以接受任意类型,但是变量实际引用的地址还是指向原来变量。

因为空接口可以接受任意类型,所以当空接口作为函数的参数类型时,该函数的参数可以接受任意类型的变量作为实参。

类型推断

类型推断可将接口变量还原为原始类型,或用来判断是否实现了某个更具体的接口类型。

当要判断空接口中值的类型时,可以使用类型断言

x.(T)
  • x:表示类型为interface{}的变量
  • T: 表示断言x可能是的类型
package main
import "fmt"

type animal interface {
    speak() string
}

type bird interface {
    animal
    fly()
}

type Magpie struct {

}

func(magpie Magpie) speak() string {
    return "叽叽喳喳"
}

func(magpie Magpie) fly() {
    fmt.Println("飞~~~~")
}

func eat(a animal) {
    fmt.Println("干饭去吧")
}

func main() {
    var magpie Magpie
    var a animal = magpie
    v, ok := a.(Magpie)
    if ok {
        fmt.Printf("%v 是一个 Magpie 类型\n", v) // {} 是一个 Magpie 类型
    } else {
        fmt.Println("断言失败")
    }
}

还是通过之前的代码例子来演示。可以发现可以通过 x.(T) 来判断当前变量 a 是否是 T 类型的实例。