使用Go中结构中的接口

时间:2012-02-23 12:41:59

标签: interface struct go

在试图理解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单独站在那里?没有名字的界面? 稍后在代码中他们甚至会尝试检查可怜的接口是否为nil:

Conn(a).frameHandler == nil

我自己的猜测是结构中的frameHandler是一个与frameHandler接口匹配的类型,最重要的是名称为frameHandler。它是否正确?呵呵,无论如何都是有趣的语言。

1 个答案:

答案 0 :(得分:9)

这一行:

    frameHandler

大致相当于:

    frameHandler frameHandler

frameHandler是该字段的名称及其类型。此外,它会将frameHandler的所有字段和方法添加到Conn,因此如果connConn,则conn.WriteClose(0)表示{{1} }}

正如the Go Programming Language Specification所说:

  

使用类型但没有显式字段名称声明的字段是匿名字段(通俗地称为嵌入字段)。必须将此类字段类型指定为类型名称conn.frameHandler.WriteClose(0)或指定为非接口类型名称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
}
匿名字段的字段和方法(§Method声明)被提升为普通字段和方法结构(§Selectors)。以下规则适用于名为T的结构类型和名为S的类型:
          
  • 如果T包含匿名字段S,则为           方法集T包括           方法集S。       
  •       
  • 如果T包含匿名字段S,则为           方法集*T包含方法集S           (其本身包括*T的方法集)。       
  •       
  • 如果T包含匿名字段S或           T,方法集*T包括           方法集*S(其本身包括方法           *T)的集合。       
  •   
字段声明后面可以跟一个可选的字符串文字标记,它成为相应字段声明中所有字段的属性。标签通过反射界面可见,但否则将被忽略。
// 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"
}