Create a struct that implements an interface. Encapsulate it into another struct. Fetch the struct / dereference it.
Why wouldn't dereferencing the pointer to the implementation gives the implementation instance?
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
%T
%T
", tmp1, tmp2, tmp3)
//dialTLS := tmp1.DialTLS
}
This code outputs...
*http2.Transport
*http.RoundTripper
*http.RoundTripper
As well, trying to access a property of the tmp1
(uncommenting dialTLS := tmp1.DialTLS
) results in compile error...
tmp1.DialTLS undefined (type http.RoundTripper has no field or method DialTLS)
...even though fmt.Printf("%+v", tmp1)
outputs...
&{DialTLS:<nil> TLSClientConfig:0xc8203ec8c0 ConnPool:<nil> DisableCompression:false MaxHeaderListSize:0 t1:<nil> connPoolOnce:{m:{state:0 sema:0} done:0} connPoolOrDef:<nil>}
What I am attempting to do is access DialTLS
in the Transport instance.
You have a type mismatch here. If you look at the documentation, you'll see that the field Transport
of the Client
struct returns an interface RoundTripper
:
type Client struct {
// Transport specifies the mechanism by which individual
// HTTP requests are made.
// If nil, DefaultTransport is used.
Transport RoundTripper
// ...
}
So, the type of tmp1
is http.RoundTripper
, though the underlying type is *http2.Transport
which implements the RoundTripper
interface.
As for tmp2
and tmp3
, they are seen as pointers to a RoundTripper
and not as **http2.Transport
.
In order to retrieve the DialTLS
field, you have to use type assertions to convert a RoundTripper
back into a Transport
:
dialTLS := client.Transport.(*http2.Transport).DialTLS