вторник, 28 мая 2019 г.

Спецификация Go: тип интерфейса (interface type)

Тип интерфейса (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
}


Читайте также:


Комментариев нет:

Отправить комментарий