简体   繁体   中英

Using an interface within a struct in Go

In trying to understand Go, I ran into this piece of code in websocket.go (snipped):

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
}

In the Conn type the frameHandler stands there all alone? An interface without a name? Later on in the code they even try check if the poor interface is nil:

Conn(a).frameHandler == nil

My own guess is that the frameHandler within the struct is a type which matches the frameHandler interface, and on top of that will have the name frameHandler . Is this correct? Hehe, fun language anyhow.

This line:

    frameHandler

is roughly equivalent to this:

    frameHandler frameHandler

in that frameHandler is both the name of the field and its type . In addition, it adds all the fields and methods of the frameHandler to the Conn , so if conn is a Conn , then conn.WriteClose(0) means conn.frameHandler.WriteClose(0) .

As the Go Programming Language Specification puts it:

A field declared with a type but no explicit field name is an anonymous field (colloquially called an embedded field). Such a field type must be specified as a type name T or as a pointer to a non-interface type name *T , and T itself may not be a pointer type. The unqualified type name acts as the field name.

 // A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4 \nstruct { \n    T1 // field name is T1 \n    *T2 // field name is T2 \n    P.T3 // field name is T3 \n    *P.T4 // field name is T4 \n    x, y int // field names are x and y \n}  
The following declaration is illegal because field names must be unique in a struct type:
 struct { \n    T // conflicts with anonymous field *T and *PT \n    *T // conflicts with anonymous field T and *PT \n    *PT // conflicts with anonymous field T and *T \n}  
Fields and methods (§Method declarations) of an anonymous field are promoted to be ordinary fields and methods of the struct (§Selectors). The following rules apply for a struct type named S and a type named T :
  • If S contains an anonymous field T , the method set of S includes the method set of T .
  • If S contains an anonymous field *T , the method set of S includes the method set of *T (which itself includes the method set of T ).
  • If S contains an anonymous field T or *T , the method set of *S includes the method set of *T (which itself includes the method set of T ).
A field declaration may be followed by an optional string literal tag , which becomes an attribute for all the fields in the corresponding field declaration. The tags are made visible through a reflection interface but are otherwise ignored.
 // A struct corresponding to the TimeStamp protocol buffer. \n// The tag strings define the protocol buffer field numbers. \nstruct { \n    microsec uint64 "field 1" \n    serverIP6 uint64 "field 2" \n    process string "field 3" \n}  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM