Go语言基础——interface
介绍
在Go语言中接口(interface)是一种类型,一种抽象的类型; interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定义一个协议(规则),只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法); 为了保护你的Go语言职业生涯,请牢记接口(interface)是一种类型;
语法
type 接口类型名 interface{
函数名(参数列表) 返回值;
}
type MyInterface interface {
test()
hello()
}
任何类型只要实现了这两个方法,都可以被看作是MyInterface类型,并且可以在需要MyInterface类型的地方使用。接口的实现是隐式的,只要一个类型实现了一个接口定义的所有方法,就被视为实现了该接口。类型可以实现多个接口,也可以空实现一个接口。
接口嵌套
type Sayer interface {
Lister
say()
}
type Lister interface {
lis()
}
type cat struct{}
// dog实现了Sayer接口
func (d cat) say() {
fmt.Println("汪汪汪")
}
// cat实现了Sayer接口
func (c cat) lis() {
fmt.Println("喵喵喵")
}
func main() {
var x Sayer // 声明一个Sayer类型的变量x
a := cat{} // 实例化一个cat
x = a // 会报错,原因缺少say方法
x.say() // 汪汪汪
x.lis()
}
接口与泛型
package main
import "fmt"
type ITest interface {
test()
hello()
}
type M struct {
Name string
}
func (M) test() {
fmt.Println("test")
}
func (M) hello() {
fmt.Println("hello")
}
func (M) world() {
fmt.Println("world")
}
func main() {
var m M = M{}
var i ITest = &m
var p any = &m
i.hello()
i.test()
// 使用i无法调用world函数
// 但是使用m可以调用world函数 m.world()
// 使用泛型和断言可以访问到结构体中的所有元素
A := p.(*M)
A.hello()
A.test()
A.world()
fmt.Println(A.Name)
}
当结构体的方法大于interface中的方法数量时,也可以被interface表示,只不过访问不到interface未声明的方法. 使用interface只能调用方法,无法访问结构体中的变量.
如何使用
参考golang标准库中sort中对于Interface的使用方式.
// It makes one call to data.Len to determine n, and O(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
n := data.Len()
quickSort(data, 0, n, maxDepth(n))
}
可以看到对于Sort函数只有一个Interface类型的参数,当我们进一步查看Interface的定义时,会发现它包含了三个方法: Len, Less, Swap. 即获取元素长度,比较元素大小,交换元素位置三个方法. 在sort中将排序抽象成了三个动作.
// A type, typically a collection, that satisfies sort.Interface can be
// sorted by the routines in this package. The methods require that the
// elements of the collection be enumerated by an integer index.
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with
// index i should sort before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}