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

时间:2014-06-06 21:22:55

标签: 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

4 个答案:

答案 0 :(得分:3)

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

  

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

     

嵌入与子类化不同的重要方法。   当我们嵌入一个类型时,那种类型的方法成为了方法   外部类型,但是当它们被调用时,方法的接收者是   内在的类型,而不是外在的类型。在我们的例子中,当读   调用bufio.ReadWriter的方法,它具有完全相同的方法   作为上述转发方法的效果;接收器是   ReadWriter的reader字段,而不是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)
}

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

该语言的属性称为嵌入: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)
}

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

答案 3 :(得分:0)

  

为什么我不必在MyTransport中为传输提供名称

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

有关详细信息,请参阅spec here

  

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

相关问题