亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang 嵌入一個帶有額外隱藏方法的接口?

Golang 嵌入一個帶有額外隱藏方法的接口?

Go
翻過高山走不出你 2021-11-29 16:56:38
我想http.ResponseWriter在結構中嵌入一個。沒關系,它確保我的結構也實現http.ResponseWriter:type MyWriter struct {    BytesWritten int    http.ResponseWriter}但是,它不再實現http.Hijacker,http.CloseNotifier或者http.Flusher即使嵌入式http.ResponseWriter通常會實現。有沒有辦法做到這一點?
查看完整描述

2 回答

?
斯蒂芬大帝

TA貢獻1827條經驗 獲得超8個贊

如果您知道響應編寫器滿足問題中列出的所有接口,那么您可以執行以下操作:


type allResponseWriterInterfaces {

    http.ResponseWriter

    http.Hijacker

    http.CloseNotifier

    http.Flusher

}


type MyWriter struct {

    BytesWritten int

    allResponseWriterInterfaces

}


...


aw, ok := w.(allResponseWriterInterfaces)

if !ok {

    // oops, response writer does not implement the interfaces

    // handle the error

}

mw := MyWriter{0, aw}

如果響應編寫器不滿足所有接口,就會變得一團糟。有關處理響應編寫器滿足 (http.ResponseWriter, http.CloseNotifier) 或 (http.ResponseWriter, http.CloseNotifier, http.Hijacker) 的情況的示例,請參閱Gorilla logger。


查看完整回答
反對 回復 2021-11-29
?
白衣染霜花

TA貢獻1796條經驗 獲得超10個贊

一種解決方案是蠻力解決方案。實際實現所有排列。我試過了,發現它有多痛苦。有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)

}

這個想法是將正確的接口嵌入到結構中。然后只暴露“正確”的方法。


查看完整回答
反對 回復 2021-11-29
  • 2 回答
  • 0 關注
  • 204 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號