2016-06-01 6 views
1

Создайте структуру, которая реализует интерфейс. Инкапсулируйте его в другую структуру. Извлеките структуру/разыщите ее.golang - получить экземпляр реализации интерфейса из структуры после разыменования

  1. Fetching получает указатель на реализацию интерфейса.
  2. Выполнение разыменования указателя приводит к другой точке интерфейса.

Почему бы не разыменовывать указатель на реализацию, дающую экземпляр реализации?

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 в экземпляре Transport.

ответ

3

У вас есть несоответствие типа здесь. Если вы посмотрите на документацию, вы увидите, что поле 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 интерфейс.

Что касается tmp2 и tmp3, они рассматриваются как указатели на RoundTripper и не как **http2.Transport.

Для того, чтобы извлечь DialTLS поля, вы должны использовать утверждение типа для преобразования RoundTripper обратно в Transport:

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

Ах, я забыл указать указатель на 'http2.Transport' в моем утверждении! Большое спасибо! – chaseisabelle