在 Go 中使用结构体中的接口

发布于 2025-01-08 14:33:31 字数 676 浏览 3 评论 0原文

在试图理解 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。这是正确的吗?呵呵,无论如何,有趣的语言。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚雾 2025-01-15 14:33:31

这一行:

    frameHandler

大致相当于:

    frameHandler frameHandler

frameHandler 既是字段的名称,又是其类型。此外,它还将 frameHandler 的所有字段和方法添加到 Conn 中,因此如果 conn 是一个 Conn >,则 conn.WriteClose(0) 表示 conn.frameHandler.WriteClose(0)

正如 Go 编程语言规范 所说:

使用类型声明但没有显式字段名称的字段是匿名字段(通俗地称为嵌入字段)。此类字段类型必须指定为类型名称 T 或指向非接口类型名称 *T 的指针,以及 T 本身可能不是指针类型。非限定类型名称充当字段名称。

// 具有四个类型为 T1、*T2、P.T3 和 *P.T4 的匿名字段的结构体
结构体{
    T1 // 字段名称为T1
    *T2 // 字段名称为 T2
    P.T3 // 字段名称为T3
    *P.T4 // 字段名称为 T4
    x, y int // 字段名称为 x 和 y
}

以下声明是非法的,因为字段名称在结构类型中必须是唯一的:

struct {
    T // 与匿名字段 *T 和 *PT 冲突
    *T // 与匿名字段 T 和 *PT 冲突
    *PT // 与匿名字段 T 和 *T 冲突
}

匿名字段的字段和方法(§方法声明)被提升为结构体的普通字段和方法(§选择器)。以下规则适用于名为 S 的结构类型和名为 T 的类型:

  • 如果 S 包含匿名字段 T,则
    S 的方法集包括
    T 的方法集。
  • 如果 S 包含匿名字段 *T,则
    S的方法集包含*T的方法集
    (它本身包括T的方法集)。
  • 如果S包含匿名字段T
    *T*S的方法集包括
    *T 的方法集(其本身包括方法
    一组T)。

字段声明后面可以跟一个可选的字符串文字标签,它成为相应字段声明中所有字段的属性。这些标签通过反射接口可见,但在其他情况下会被忽略。

// 对应TimeStamp协议缓冲区的结构体。
// 标记字符串定义协议缓冲区字段编号。
结构体{
    微秒 uint64“字段 1”
    serverIP6 uint64“字段 2”
    处理字符串“字段 3”
}

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
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
}

The following declaration is illegal because field names must be unique in a struct type:

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
}

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.
// The tag strings define the protocol buffer field numbers.
struct {
    microsec  uint64 "field 1"
    serverIP6 uint64 "field 2"
    process   string "field 3"
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文