Interface types
接口类型指定一个 方法集,称为其接口。接口类型的变量可以利用接口的超集方法集来存储任何类型的值。这种方法被称为实现接口。接口类型的未初始化变量的值为nil
。
InterfaceType = "interface" "{" { MethodSpec ";" } "}" .
MethodSpec = MethodName Signature | InterfaceTypeName .
MethodName = identifier .
InterfaceTypeName = TypeName .
与所有方法集一样,在接口类型中,每个方法必须具有一个唯一且非[空](golang.org/ref/ spec#Blank_identifier)名称。
// 一个简单的文件接口
interface {
Read([]byte) (int, error)
Write([]byte) (int, error)
Close() error
}
interface {
String() string
String() string // 不合法: String 名称已经存在
_(x int) // 不合法: 方法名称不能为空
}
有很多类型都可以实现接口。例如,如果两种不同的类型 S1
和 S2
都具有方法集
func (p T) Read(p []byte) (n int, err error) { return … }
func (p T) Write(p []byte) (n int, err error) { return … }
func (p T) Close() error { return … }
(其中 T
代表 S1
或 S2
),S1
和 S2
都实现了 File
接口(S1
和 S2
可能拥有或共享其他的方法,但是这些我们不考虑)
类型实现包含其方法的任何子集的任何接口,因此可以实现几个不同的接口。例如,所有类型都实现了空接口:
interface{}
同样,遵从 类型声明 中的接口规范来定义名为 Locker
的接口:
type Locker interface {
Lock()
Unlock()
}
如果 S1
和 S2
同样实现了
func (p T) Lock() { … }
func (p T) Unlock() { … }
那么就可以说它们同时实现了 Locker
接口和 File
接口。
接口 T
可以使用一个(合法的)接口类型名称 E
来代替方法声明。这被称作 T
中的 嵌入接口 E
;它将 E
的所有(包括导出和未导出)方法添加到接口T
。
type ReadWriter interface {
Read(b Buffer) bool
Write(b Buffer) bool
}
type File interface {
ReadWriter // 与添加 ReadWriter 中的所有方法相同
Locker // 与添加 Locker 中的所有方法相同
Close()
}
type LockedFile interface {
Locker
File // 不合法: Lock 和 Unlock 不是唯一
Lock() // 不合法: Lock 不是唯一
}
一个接口类型T
不能递归嵌入自己或者任何嵌入了自己的接口类型。
// 不合法: 不可以嵌入自己
type Bad interface {
Bad
}
// 不合法:不可以通过 Bad2 间接的嵌入自己
type Bad1 interface {
Bad2
}
type Bad2 interface {
Bad1
}
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。