Go 接口类型

什么是接口

Go 语言中的接口用于定义一组行为。其中,每个行为都是一个由一个方法进行声明的。

在声明一个接口时,只需要声明方法的名称,方法的参数列表以及结果列表即可。如:

1
2
3
4
type Person interface {
Listen(string)
Say() string
}

Person 接口就是定义了一组与 “Person” 相关的行为。

接口类型是无法实例化的,这意味着无法使用 new 或 make 函数来创建接口类型的值。同样的,也不可以使用一个字面量来表示某个接口的值。

接口的实现

如果一个数据类型 T 的方法集合中包含了接口 I 声明的所有方法,那么它就是 I 的实现类型。即 “Duck Typing”。

例如:

1
2
3
4
5
6
7
8
9
type T string

func (t *T) Listen(word string) {
// .....
}

func (t *T) Say() string {
return "T"
}

T 的所有指针方法都包含了 Person 所声明的方法,因此 *T 类型就是 Person 的实现类型。⚠️注意的是,T 类型并不是, *T 类型才是。

在 Go 中,数据类型之间并不存在继承关系,只有组合关系。这意味着,可以在一个接口类型的声明中嵌入任意数量的其他接口类型。让一组行为包含其他的行为组。例如:

1
2
3
4
type TPerson interface {
Person
Eat(string)
}

动态类型与静态类型

有如下两个变量:

1
2
var t T = "abc"
var p Person = &t

被赋予接口类型变量的值称为动态值, &t 就是 p 的动态值;

动态值的类型就是动态类型,p 的动态类型是 *T;

接口变量本身的类型就是 静态类型,p 的静态类型就是 Person,并且一直都是。

此外,如果有另外一个类型 *T2 也实现了 Person 接口,并且 *T2 类型的值被赋予了 p, 那么 p 的动态类型就变为了 *T2.

在接口类型的变量被赋值之前,它的动态类型并不存在。


Go 接口类型
https://blog.zhangliangliang.cc/post/go-interface.html
作者
Bobby Zhang
发布于
2019年5月4日
许可协议