golang - 取消引用后从struct获取接口实现实例

时间:2016-06-01 00:44:39

标签: go struct types interface dereference

创建实现接口的结构。 将其封装到另一个结构中。 获取结构/取消引用它。

  1. 获取指向接口实现的指针。
  2. 取消引用指针会导致另一个接口点。
  3. 为什么不解引用指向实现的指针给出实现实例?

    package main
    
    import (
        "fmt"
        "net/http"
    
        "golang.org/x/net/http2"
    )
    
    func main() {
        transport := &http2.Transport{}
        client := &http.Client{Transport: transport}
    
        tmp1 := client.Transport
        tmp2 := &client.Transport
        tmp3 := &tmp1
    
        fmt.Printf("%T\n%T\n%T\n", tmp1, tmp2, tmp3)
    
        //dialTLS := tmp1.DialTLS
    }
    

    此代码输出......

    *http2.Transport
    *http.RoundTripper
    *http.RoundTripper
    

    同样,尝试访问tmp1的属性(取消注释dialTLS := tmp1.DialTLS)会导致编译错误......

    tmp1.DialTLS undefined (type http.RoundTripper has no field or method DialTLS)
    

    ......即使fmt.Printf("%+v", tmp1)输出......

    &{DialTLS:<nil> TLSClientConfig:0xc8203ec8c0 ConnPool:<nil> DisableCompression:false MaxHeaderListSize:0 t1:<nil> connPoolOnce:{m:{state:0 sema:0} done:0} connPoolOrDef:<nil>}
    

    我尝试做的是访问传输实例中的DialTLS

1 个答案:

答案 0 :(得分:4)

您的类型不匹配。如果查看文档,您将看到Transport结构的字段Client返回接口RoundTripper

type Client struct {
    // Transport specifies the mechanism by which individual
    // HTTP requests are made.
    // If nil, DefaultTransport is used.
    Transport RoundTripper

    // ...
}

因此,tmp1的类型为http.RoundTripper,但基础类型为*http2.Transport,它实现了RoundTripper接口。

至于tmp2tmp3,它们被视为指向RoundTripper而非**http2.Transport的指针。

要检索DialTLS字段,您必须使用类型断言将RoundTripper转换回Transport

dialTLS := client.Transport.(*http2.Transport).DialTLS