对多次组成的对象进行类型断言

时间:2018-11-27 17:04:58

标签: go

是否可以对多次组成的对象的任何子类型进行类型声明?

例如,说我有以下对象:

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

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

我最终可能会遇到这样的事情:

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

现在如果我有一个w http.ResponseWriter,是否可以将其“投射”到MyOtherResponseWriterMyResponseWriter上?

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

FWIW,我的实际用例是,在一个http.Handler中,我正在处理一个被包装多次的http.ResponseWriter,但我无法访问我感兴趣的其他方法,以及我的原因这样做是为了允许中间件访问由处理程序写入的数据。

谢谢

2 个答案:

答案 0 :(得分:0)

根据您要查找的逻辑类型,您可以执行以下操作:

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

请注意,代码始终必须“知道”它具有哪种类型的ResponseWriter

答案 1 :(得分:0)

如果您正在寻找一个任意方法,则在您的类型内嵌套了任意数量级别的字段上,您需要声明每个级别的类型以获取候选字段。

例如,如果要使用上面显示的类型确定是否有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