繁体   English   中英

在Go中仅将结构类型指定为结构成员是什么意思?

[英]What does it mean to specify just a struct type as a struct member in Go?

我知道我可以写这样的代码,但我不知道它是如何工作的:

type MyTransport struct {
  http.Transport
}

func (myT *MyTransport) RoundTrip(r *http.Request) (*http.Response, error) {
  return myT.Transport.RoundTrip(r)
}

http.Transport只是一个结构,对吗? 它没有名字。 那么myT.Transport如何运作? 为什么我不必在MyTransport为传输提供名称,例如将其声明为ht http.Transport

这是一个嵌入式结构,来自http://golang.org/doc/effective_go.html#embedding

通过直接嵌入结构,我们避免了这种记账。 嵌入式类型的方法是免费的,这意味着bufio.ReadWriter不仅具有bufio.Reader和bufio.Writer的方法,它还满足所有三个接口:io.Reader,io.Writer和io.ReadWriter。

嵌入与子类化不同的重要方法。 当我们嵌入一个类型时,该类型的方法成为外部类型的方法,但是当它们被调用时,方法的接收者是内部类型,而不是外部类型。 在我们的示例中,当调用bufio.ReadWriter的Read方法时,它与上面写出的转发方法具有完全相同的效果; 接收器是ReadWriter的读取器字段,而不是ReadWriter本身。

嵌入也可以是一个简单的方便。 此示例显示嵌入字段以及常规命名字段。

TL; DR:

这或多或少是“oop”继承的方式:

type MyTransport struct {
    http.Transport
}

//without this function, calling myT.RoundTrip would actually call myT.Transport.RoundTrip
func (myT *MyTransport) RoundTrip(r *http.Request) (*http.Response, error) {
    return myT.Transport.RoundTrip(r)
}

这称为嵌入。 如果您还没有阅读Effective Go,那么您应该这样做。 http://golang.org/doc/effective_go.html#embedding

简而言之,嵌入式http.Transport的方法可以通过MyTransport结构访问。

该语言的属性称为嵌入: http//golang.org/doc/effective_go.html#embedding

如果文档压倒了相关部分以理解你为什么写

type MyTransport struct {
  http.Transport
}

代替

type MyTransport struct {
  transport http.Transport
}

这是 :

// ReadWriter stores pointers to a Reader and a Writer.
// It implements io.ReadWriter.
type ReadWriter struct {
    *Reader  // *bufio.Reader
    *Writer  // *bufio.Writer
}

嵌入式元素是结构的指针,当然必须初始化以指向有效的结构,然后才能使用它们。 ReadWriter结构可以写成

type ReadWriter struct {
    reader *Reader
    writer *Writer
}

但是为了推广字段的方法并满足io接口,我们还需要提供转发方法,如下所示:

func (rw *ReadWriter) Read(p []byte) (n int, err error) {
    return rw.reader.Read(p)
}

将其视为“将所有结构定义及其方法复制到此结构”

为什么我不必在MyTransport中为传输命名

您已创建匿名字段,因此非限定类型名称将充当字段名称

有关详细信息,请参阅此处规范

使用类型但没有显式字段名称声明的字段是匿名字段,也称为嵌入字段或在结构中嵌入类型。 必须将嵌入类型指定为类型名称T或指向非接口类型名称* T的指针,并且T本身可能不是指针类型。 非限定类型名称充当字段名称

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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