基本介绍
- Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
- 接口可以让我们将不同的类型绑定到一组公共的方法上,从而实现多态和灵活的设计。
- Go 语言中的接口是隐式实现的,也就是说,如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口。
- 一个类型可以实现多个接口,一个接口也可以被多个类型实现。
基本使用
type Animal interface { Run() Say() } type Horse struct { Name string } type Dog struct { Name string } func (h *Horse) Run(){ fmt.Println("Horse Run") } func (h *Horse) Say(){ fmt.Println("Horse Say") } func (d *Dog) Run(){ fmt.Println("Dog Run") } func (d *Dog) Say(){ fmt.Println("Dog Say") } func animalAction(animal Animal){ animal.Run() animal.Say() } func main(){ horse := &Horse{ "Horse", } dog := &Dog{ "dog", } fish := &Fish{ "fish", } animalAction(horse) // Horse Run Horse Say animalAction(dog)// Dog Run Dog Say }
代码解释

(图片来源网络,侵删)
- 我们先定义了一个动物的接口,接口有两个方法签名
- 定义了马的结构体,并实现了接口的两个方法,所以这个马的结构体实现了动物接口
- 定义了狗的结构体,并实现了接口的两个方法,所以这个狗的结构体实现了动物接口
- 定义一个 animalAction 函数,参数是 接口类型,意味着只要实现了该接口的类型都可以传
- 在 main 函数中,分别实例化了一个马和一个狗并传入 animalAction ,从而实现了多态
空接口 interface{}
- 空接口是指没有定义任何方法的接口。
- 因此任何类型都实现了空接口。
- 空接口类型的变量可以存储任意类型的变量。
- 使用空接口实现可以接收任意类型的函数参数。
- 把一个空接口类型的值赋值给一个类型需要通过断言。
类型断言
我们可以通过变量后面 . (类型)的语法对变量进行断言
func demo1(){ var i interface{} var str string i = "adf" str = i.(string) fmt.Print(str) // abc }
func demo2(){ var i interface{} var number int i = 123 number = i.(int) fmt.Print(number) // 123 }
函数传参
- 可以把接口类型的数据传入到函数里。
- 想知道断言是否成功可以通过接口第二个参数。
func demo3(i interface{}){ value1 ,ok1 := i.(string) if ok1 { fmt.Printf("i is string,value:%s\n",value1) } value2 ,ok2 := i.(int) if ok2 { fmt.Printf("i is int,value:%d\n",value2) } } func main(){ demo3(1) // i is int,value:1 demo3("abc") // i is string,value:abc }
switch 判断类型
如果觉得上面那种 if 判断多个类型的时候很麻烦,我们可以使用 switch i.(type) 语法来判断多个类型。

(图片来源网络,侵删)
func demo4(i interface{}){ switch i.(type) { case int: fmt.Println("is int") case string: fmt.Println("is string") case bool: fmt.Println("is bool") } } func main(){ demo4(1)//is int demo4("abc")// is string demo4(true)//is bool }