Использование интерфейса в структуре в Go - PullRequest
1 голос
/ 23 февраля 2012

Пытаясь понять Go, я наткнулся на этот фрагмент кода в websocket.go (отрывался):

type frameHandler interface {
    HandleFrame(frame frameReader) (r frameReader, err error)
    WriteClose(status int) (err error)
}

// Conn represents a WebSocket connection.
type Conn struct {
    config  *Config
    request *http.Request
    .
    .
    frameHandler
    PayloadType        byte
    defaultCloseStatus int
}

В типе Conn frameHandler стоит там один?Интерфейс без имени?Позже в коде они даже пытаются проверить, имеет ли плохой интерфейс ноль:

Conn(a).frameHandler == nil

Я думаю, что frameHandler в структуре - это тип, который соответствует интерфейсу frameHandler, и в верхней частиэто будет иметь имя frameHandler.Это правильно?Хе-хе, забавный язык в любом случае.

1 Ответ

9 голосов
/ 23 февраля 2012

Эта строка:

    frameHandler

примерно эквивалентна этому:

    frameHandler frameHandler

в том смысле, что frameHandler является и именем поля и его типа .Кроме того, он добавляет все поля и методы frameHandler к Conn, поэтому, если conn является Conn, то conn.WriteClose(0) означает conn.frameHandler.WriteClose(0).

как спецификация языка программирования Go означает:

Поле, объявленное с типом, но без явного имени поля, является анонимным полем (в разговорной речи называется встроенным полем).Такой тип поля должен быть указан как имя типа T или как указатель на имя неинтерфейсного типа *T, а сам T может не являться типом указателя.Неквалифицированное имя типа действует как имя поля.

// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
struct {
    T1        // field name is T1
    *T2       // field name is T2
    P.T3      // field name is T3
    *P.T4     // field name is T4
    x, y int  // field names are x and y
}
Следующее объявление недопустимо, потому что имена полей должны быть уникальными в типе структуры:
struct {
    T         // conflicts with anonymous field *T and *P.T
    *T        // conflicts with anonymous field T and *P.T
    *P.T      // conflicts with anonymous field T and *T
}
Поля и методы (объявления метода) анонимного поля повышаются до обычных полей и методов структуры (§Selectors).Следующие правила применяются для типа структуры с именем
S и типа с именем T:
  • Если S содержит анонимное поле T, набор методов S включает набор методов:T.
  • Если S содержит анонимное поле *T, набор методов S включает набор методов *T (который сам включает набор методов T).
  • Если S содержит анонимное поле T или *T, набор методов *S включает набор методов *T (который сам включает набор методов T).
За объявлением поля может следовать необязательный строковый литерал tag , который становится атрибутом для всех полей в соответствующем объявлении поля.Теги становятся видимыми через интерфейс отражения, но в остальном игнорируются.
// A struct corresponding to the TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers.
struct {
    microsec  uint64 "field 1"
    serverIP6 uint64 "field 2"
    process   string "field 3"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...