Go语言基础之Interface

114 阅读2分钟

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)
}