如何实现方法覆盖接口

时间:2015-02-09 12:08:50

标签: go

我编写了一个包装http.ResponseWriter的工具,并提供了一种新方法来渲染模板。

 type MyResponseWriter interface {
      http.ResponseWriter
      Render(tmpl string, v interface{}
 }
 type myResponseWriter struct {
     server *Server
     http.ResponseWriter
 }

 func (rw *myResponseWriter) Render(tmpl string, v interface{}) {
      rw.server.Render(rw, tmpl, v)
 }

现在,我想覆盖MyResponseWriter的{​​{1}}方法,将gzip压缩作为可插入过滤器启用,而不知道Write的实现。

我在这里写了一个MyResponseWriter,它用作GzipResponseWriter,所以它可以插件:

MyResponseWriter

但是,当我启用type GzipResponseWriter struct { MyResponseWriter } func (grw *GzipResponseWriter) Write(data []byte) (int, error) { return GzipWrite(grw.MyResponseWriter, data) } 然后拨打GzipResponseWriter时,它仍然会调用Render MyResponseWriter,而不是Write, 并且浏览器显示"内容编码错误"。

这一切都是因为当我拨打GzipResponseWriter的{​​{1}}时,真正的方法接收者仍然是RenderGzipResponseWriter来电{{1 } {' s myResponseWriter

我认为我们对库/框架提供的接口的某些方法进行更改是一个常见的要求,然后此接口的其他方法将调用这些新方法而不是旧方法。在我的问题中,要求是gzip压缩,但是这个功能在Go中很难实现。

是否有实施此提案的解决方案? 感谢。

1 个答案:

答案 0 :(得分:0)

out io.Writer添加新字段myResponseWriter,并添加使用此io.Write()字段的out方法:

type myResponseWriter struct {
    out io.Writer
    server *Server
    http.ResponseWriter
}

func (m *myResponseWriter) Write(b []byte) (int, error) {
    return m.out.Write(b)
}

默认情况下,同样http.ResponseWriter也设置为out字段。

当你想切换到Gzipped响应时,只需将out作者包装成这样:

out = gzip.NewWriter(out)

由于myResponseWriter.Write()使用out字段,您的Render()方法将通过gzip编写器发送其输出。