如何实现方法覆盖接口
问题描述:
我写了一个工具,它包装了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
的Write
方法来启用gzip压缩,作为一个可插入过滤器不知道的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
, 和浏览器显示“内容编码错误”。
这时候,我所说的GzipResponseWriter
的Render
的一切,因为,真正的方法接收器仍是myResponseWriter
,并Render
电话myResponseWriter
的Write
。
我认为这是一个常见的需求,我们对库/框架提供的接口的某些方法进行了更改,然后此接口的其他方法将调用这些新方法而不是旧方法。在我的问题中,需求是gzip压缩,但这个特性在Go中很难实现。
是否有解决方案来实现此提议? 谢谢。
答
添加一个新的领域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
场了。
而当你想切换到Gzip压缩的响应,只是包裹out
作家是这样的:
out = gzip.NewWriter(out)
由于myResponseWriter.Write()
使用out
场,你Render()
方法将通过gzip的作家发送它的输出。
我假设你想写'类型GzipResponseWriter接口{'(缺少'interface'关键字)... – icza 2015-02-09 12:22:43
谢谢。这是一个结构。 – cosiner 2015-02-09 12:28:11
那么,这改变了图片,我不得不重写我的答案。 – icza 2015-02-09 12:36:20