白衣染霜花
一种解决方案是蛮力解决方案。实际实现所有排列。我试过了,发现它有多痛苦。有18种排列!所以这是一个通用的包装器。优点是您可以根据需要多次重复使用此包装器。关键是像这样定义一个接口:// ResponseWriterTo can proxy requests to an underlying http.ResponseWriter.// It is used with CustomResponseWriter to wrap an http.ResponseWriter with// custom behavior.type ResponseWriterTo interface { HeaderTo(w http.ResponseWriter) http.Header WriteHeaderTo(w http.ResponseWriter, s int) WriteTo(w http.ResponseWriter, b []byte) (n int, err error) // Additional methods that http.ResponseWriter sometimes implements. CloseNotifyTo(w http.CloseNotifier) <-chan bool FlushTo(w http.Flusher) HijackTo(w http.Hijacker) (net.Conn, *bufio.ReadWriter, error) // ReaderFrom is used by the http package to optimize reads from TCP // connections or from files. ReadFromTo(w io.ReaderFrom, r io.Reader) (n int64, err error)}这样我们就可以定义一个自定义的包装函数(这是详细的部分):// CustomResponseWriter creates a http.ResponseWriter that implements as many// hidden interfaces from the base http.ResponseWriter as are available.func CustomResponseWriter(base http.ResponseWriter, custom ResponseWriterTo) http.ResponseWriter { rw := &customResponseWriter{base: base, custom: custom} // the base http.ResponseWriter can implement many hidden interfaces, // so check all permutations type HCFR interface { http.ResponseWriter http.Hijacker http.CloseNotifier http.Flusher io.ReaderFrom } if _, ok := base.(HCFR); ok { return struct { HCFR }{rw} } type HCF interface { http.ResponseWriter http.Hijacker http.CloseNotifier http.Flusher } if _, ok := base.(HCF); ok { return struct { HCF }{rw} } type HCR interface { http.ResponseWriter http.Hijacker http.CloseNotifier io.ReaderFrom } if _, ok := base.(HCR); ok { return struct { HCR }{rw} } type HFR interface { http.ResponseWriter http.Hijacker http.Flusher io.ReaderFrom } if _, ok := base.(HFR); ok { return struct { HFR }{rw} } type CFR interface { http.ResponseWriter http.CloseNotifier http.Flusher io.ReaderFrom } if _, ok := base.(CFR); ok { return struct { CFR }{rw} } type HC interface { http.ResponseWriter http.Hijacker http.CloseNotifier } if _, ok := base.(HC); ok { return struct { HC }{rw} } type HF interface { http.ResponseWriter http.Hijacker http.Flusher } if _, ok := base.(HF); ok { return struct { HF }{rw} } type CF interface { http.ResponseWriter http.CloseNotifier http.Flusher } if _, ok := base.(CF); ok { return struct { CF }{rw} } type HR interface { http.ResponseWriter http.Hijacker io.ReaderFrom } if _, ok := base.(HR); ok { return struct { HR }{rw} } type CR interface { http.ResponseWriter http.CloseNotifier io.ReaderFrom } if _, ok := base.(CR); ok { return struct { CR }{rw} } type FR interface { http.ResponseWriter http.Flusher io.ReaderFrom } if _, ok := base.(FR); ok { return struct { FR }{rw} } type H interface { http.ResponseWriter http.Hijacker } if _, ok := base.(H); ok { return struct { H }{rw} } type C interface { http.ResponseWriter http.CloseNotifier } if _, ok := base.(C); ok { return struct { C }{rw} } type F interface { http.ResponseWriter http.Flusher } if _, ok := base.(F); ok { return struct { F }{rw} } type R interface { http.ResponseWriter io.ReaderFrom } if _, ok := base.(R); ok { return struct { R }{rw} } return struct { http.ResponseWriter }{rw}}// customResponseWriter allows us to adapt a ResponseWriterTo to a ResponseWriter.type customResponseWriter struct { base http.ResponseWriter custom ResponseWriterTo}func (w *customResponseWriter) Header() http.Header { return w.custom.HeaderTo(w.base) }func (w *customResponseWriter) Write(b []byte) (int, error) { return w.custom.WriteTo(w.base, b) }func (w *customResponseWriter) WriteHeader(s int) { w.custom.WriteHeaderTo(w.base, s) }func (w *customResponseWriter) CloseNotify() <-chan bool { return w.custom.CloseNotifyTo(w.base.(http.CloseNotifier))}func (w *customResponseWriter) Flush() { w.custom.FlushTo(w.base.(http.Flusher)) }func (w *customResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { return w.custom.HijackTo(w.base.(http.Hijacker))}func (w *customResponseWriter) ReadFrom(r io.Reader) (n int64, err error) { return w.custom.ReadFromTo(w.base.(io.ReaderFrom), r)}这个想法是将正确的接口嵌入到结构中。然后只暴露“正确”的方法。