代码之家  ›  专栏  ›  技术社区  ›  Sylvain

对多次组合的对象的类型断言

go
  •  1
  • Sylvain  · 技术社区  · 7 年前

    可以对多次组合的对象的任何子类型进行类型断言吗?

    例如,假设我有以下对象:

    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 回复  |  直到 7 年前
        1
  •  0
  •   poy    7 年前

    根据您正在寻找的逻辑类型,您可以执行以下操作:

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

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

        2
  •  0
  •   JimB    7 年前

    如果要在嵌套在自己类型中任意数量级别的字段上寻找任意方法,则需要断言每个级别的类型以获得候选字段。

    例如,如果你想确定你是否有 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