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
}
}