Тип интерфейса (interface type) определяет набор методов, называемый его интерфейсом. Переменная типа интерфейса может хранить значение любого типа с набором методов, который является любым надмножеством интерфейса. Говорят, что такой тип реализует интерфейс. Значение не инициализированной переменной типа интерфейса равно nil.
InterfaceType = "interface" "{" { MethodSpec ";" } "}" .
MethodSpec = MethodName Signature | InterfaceTypeName .
MethodName = identifier .
InterfaceTypeName = TypeName .
Как и во всех наборах методов, в типе интерфейса каждый метод должен иметь уникальное непустое имя.
// Простой File интерфейс
interface {
Read(b Buffer) bool
Write(b Buffer) bool
Close()
}
Несколько типов могут реализовывать интерфейс. Например, если два типа S1 и S2 имеют набор методов
func (p T) Read(b Buffer) bool { return … }
func (p T) Write(b Buffer) bool { return … }
func (p T) Close() { … }
(где T обозначает либо S1, либо S2), тогда интерфейс File реализуется как S1, так и S2, независимо от того, какие другие методы S1 и S2 могут иметь или совместно использовать.
Тип реализует любой интерфейс, содержащий любое подмножество его методов, и поэтому может реализовывать несколько отдельных интерфейсов. Например, все типы реализуют пустой интерфейс:
interface{}
Точно так же рассмотрите следующую спецификацию интерфейса, которая появляется в объявлении типа, чтобы определить интерфейс с именем Locker:
type Locker interface {
Lock()
Unlock()
}
Если S1 и S2 также реализуют
func (p T) Lock() { … }
func (p T) Unlock() { … }
значит они реализуют интерфейс Locker, а также интерфейс File.
Интерфейс T может использовать (возможно, квалифицированное) имя типа интерфейса E вместо спецификации метода. Это называется встраиванием интерфейса E в T; он добавляет все (экспортируемые и не экспортируемые) методы 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 не может быть встроенным сам по себе или любой интерфейсный тип, который встраивает T, рекурсивно.
// недопустимо: Bad не может встраивать сам себя
type Bad interface {
Bad
}
// недопустимо: Bad1 не может встраивать сам себя используя Bad2
type Bad1 interface {
Bad2
}
type Bad2 interface {
Bad1
}
Читайте также:
Комментариев нет:
Отправить комментарий