Утверждение типа над объектом, составленное несколько раз - PullRequest
0 голосов
/ 27 ноября 2018

Можно ли сделать утверждение типа по любому из подтипов объекта, составленного несколько раз?

Например, скажем, у меня есть следующие объекты:

type MyResponseWriter struct {
    http.ResponseWriter
    // ...
}

type MyOtherResponseWriter struct {
    http.ResponseWriter
    // ...
}

Я мог бы закончитьчто-то вроде этого:

rw := &MyOtherResponseWriter{ResponseWriter: &MyResponseWriter{ResponseWriter: w}}

Теперь, если у меня есть w http.ResponseWriter, можно ли его «привести» к MyOtherResponseWriter или MyResponseWriter?

cw.(*MyResponseWriter) // panic: interface conversion: http.ResponseWriter is *MyOtherResponseWriter, not *MyResponseWriter

FWIW, мой фактический случай использования состоит в том, что в http.Handler я имею дело с http.ResponseWriter, который был обернут несколько раз, и мне не удается получить доступ к дополнительному методу, который меня интересует, и причину, по которой я хочу это сделатьэто позволяет промежуточному программному обеспечению получать доступ к данным, записанным обработчиком.

Спасибо

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Если вы ищете произвольный метод, для поля, вложенного в произвольное количество уровней глубоко в ваших собственных типах, вам нужно установить тип каждого уровня, чтобы получить поле-кандидат.

Например, если вы хотите определить, есть ли у вас http.Flusher, используя типы, показанные выше, вы можете использовать такую ​​функцию:

func getFlusher(rw http.ResponseWriter) (http.Flusher, bool) {
    switch t := rw.(type) {
    case http.Flusher:
        return t, true
    case *MyResponseWriter:
        return getFlusher(t.ResponseWriter)
    case *MyOtherResponseWriter:
        return getFlusher(t.ResponseWriter)
    default:
        return nil, false
    }
}

https://play.golang.org/p/Li80bUzYTft

0 голосов
/ 27 ноября 2018

В зависимости от того, какой тип логики вы ищете, вы можете сделать что-то вроде:

var rw http.ResponseWriter = &MyResponseWriter{
  ResponseWriter: &MyOtherResponseWriter{}
}
cw := rw.(*MyResponseWriter).ResponseWriter.(*MyOtherResponseWriter)

Обратите внимание, что код всегда должен "знать", какой тип ResponseWriter он имеет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...