dst3605528 2015-02-09 12:08 采纳率: 0%
浏览 78

如何实现接口的方法覆盖

I wrote a tool which wraps http.ResponseWriter and supplies a new method to render a template.

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

Now, I want to override MyResponseWriter's Write method to enable gzip compression as a pluggable filter without knowing the implementation of MyResponseWriter.

I wrote a GzipResponseWriter here, and it's used as an MyResponseWriter, so it's pluggable:

type GzipResponseWriter struct {
     MyResponseWriter
}

func (grw *GzipResponseWriter) Write(data []byte) (int, error) {
      return GzipWrite(grw.MyResponseWriter, data)       
}

But, when I enable GzipResponseWriter then call Render, it still calls the MyResponseWriter's Write, rather than GzipResponseWriter, and the browser show me an "Content Encoding Error".

That's all because of when I call Render of a GzipResponseWriter, the real method receiver is still the myResponseWriter, and Render calls myResponseWriter's Write.

I think it's a common requirement that we make changes on some methods of a interface that libraries/frameworks supplied, then other methods of this interface will call these new methods rather than old methods. In my question, the requirement is gzip compression, but this feature is so difficult to implement in Go.

Is there a solution to implements this proposal? Thanks.

  • 写回答

1条回答 默认 最新

  • dongsuo9982 2015-02-09 12:21
    关注

    Add a new field out io.Writer to the myResponseWriter, and also add the io.Write() method which uses this out field:

    type myResponseWriter struct {
        out io.Writer
        server *Server
        http.ResponseWriter
    }
    
    func (m *myResponseWriter) Write(b []byte) (int, error) {
        return m.out.Write(b)
    }
    

    And by default set the same http.ResponseWriter to the out field too.

    And when you want to switch to Gzipped response, simply wrap the out writer like this:

    out = gzip.NewWriter(out)
    

    Since myResponseWriter.Write() uses the out field, your Render() method will send its output through the gzip writer.

    评论

报告相同问题?

悬赏问题

  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比