Go 问答之如何理解 Go 中的接口

如何理解 Golang 中的接口。我的认为,要理解 Go 的接口,必定先了解下鸭子模型。bash

鸭子模型

那什么鸭子模型?函数

鸭子模型的解释,一般会用了一个很是有趣的例子,一个东西到底是不是鸭子,取决于它的能力。游泳起来像鸭子、叫起来也像鸭子,那么就能够是鸭子。spa

动态语言,好比 Python 和 Javascript 自然支持这种特性,不过相对于静态语言,动态语言的类型缺少了必要的类型检查。设计

Go 接口设计和鸭子模型有密切关系,但又和动态语言的鸭子模型有所区别,在编译时,便可实现必要的类型检查。code

什么是 Go 接口

Go 接口是一组方法的集合,能够理解为抽象的类型。它提供了一种非侵入式的接口。任何类型,只要实现了该接口中方法集,那么就属于这个类型。接口

举个例子,假设定义一个鸭子的接口。以下:ip

type Duck interface {
	Quack()   // 鸭子叫
	DuckGo()  // 鸭子走
}
复制代码

假设如今有一个鸡类型,结构以下:get

type Chicken struct {
}

func (c Chicken) IsChicken() bool {
	fmt.Println("我是小鸡")
}
复制代码

这只鸡和通常的小鸡不同,它比较聪明,也能够作鸭子能作的事情。string

func (c Chicken) Quack() {
	fmt.Println("嘎嘎")
}

func (c Chicken) DuckGo() {
	fmt.Println("大摇大摆的走")
}
复制代码

注意,这里只是实现了 Duck 接口方法,并无将鸡类型和鸭子接口显式绑定。这是一种非侵入式的设计。it

咱们定义一个函数,负责执行鸭子能作的事情。

func DoDuck(d Duck) {
	d.Quack()
	d.DuckGo()
}
复制代码

由于小鸡实现了鸭子的全部方法,因此小鸡也是鸭。那么在 main 函数中就能够这么写了。

func main() {
	c := Chicken{}
	DoDuck(c)
}
复制代码

执行正常。如此是否是很相似于其余语言的多态,其实这就是 Go 多态的实现方法。

空接口

简单说下空 interface。

若是一个 interface 中若是没有定义任何方法,即为空 interface,表示为 interface{}。如此一来,任何类型就都能知足它,这也是为何当函数参数类型为 interface{} 时,能够给它传任意类型的参数。

示例代码,以下:

package main

import "fmt"

func main() {
	var i interface{} = 1
	fmt.Println(i)
}
复制代码

更经常使用的场景,Go 的 interface{} 经常会被做为函数的参数传递,用以帮助咱们实现其余语言中的泛型效果。Go 中暂时不支持 泛型,不过 Go 2 的方案中彷佛将支持泛型。

总结

回答结束,作个简单总结。

理解 Go 接口要记住一点,接口是一组方法的集合,这句话很是重要,理解了这句话,再去理解 Go 的其余知识,好比类型、多态、空接口、反射、类型检查与断言等就会容易不少。

相关文章
相关标签/搜索