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

Is it possible to do type assertion over any of the sub type of an object composed several times?

Example, say I have the following objects:

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

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

I might end up with something like this:

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

Now if I have a w http.ResponseWriter, is it possible to 'cast' it to either a MyOtherResponseWriter or a MyResponseWriter ?

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

FWIW, my actual use case is that in a http.Handler I'm dealing with a http.ResponseWriter that's been wrapped several times and I fail to access the extra method that interests me, and the reason I want to do this is to allow a middleware to access data written by the handler.

Thanks

Depending on what type of logic you are looking for you could do something like:

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

Notice that the code always has to "know" which type of ResponseWriter it has.

If you're looking for an arbitrary method, on a field nested an arbitrary number of levels deep within your own types, you need to assert each level's type to get the candidate field.

For example, if you wanted to determine if you have an http.Flusher using the types shown above, you could use a function like so:

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