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

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

恐慌:最后一個參數需要是 http.HandlerFunc 類型

恐慌:最后一個參數需要是 http.HandlerFunc 類型

Go
藍山帝景 2023-05-22 15:36:47
我有這個輔助函數,可以正常編譯:func Middleware(adapters ...interface{}) http.HandlerFunc {    log.Info("length of adapters:", len(adapters))    if len(adapters) < 1 {        panic("Adapters need to have length > 0.");    }    h, ok := (adapters[len(adapters)-1]).(http.HandlerFunc)    if ok == false {        panic("Last argument needs to be of type http.HandlerFunc") // ERROR HERE    }    adapters = adapters[:len(adapters)-1]    for _, adapt := range adapters {        h = (adapt.(AdapterFunc))(h)    }    return h}我這樣稱呼它:router.HandleFunc("/share", h.makeGetMany(v)).Methods("GET")func (h Handler) makeGetMany(v Injection) http.HandlerFunc {    return mw.Middleware(        mw.Allow("admin"),        func(w http.ResponseWriter, r *http.Request) {            log.Println("now we are sending response.");            json.NewEncoder(w).Encode(v.Share)        },    )}問題是我收到此錯誤,但我無法弄清楚原因:    panic: Last argument needs to be of type http.HandlerFunc    goroutine 1 [running]:    huru/mw.Middleware(0xc420083d40, 0x2, 0x2, 0xc42011f3c0)            /home/oleg/codes/huru/api/src/huru/mw/middleware.go:301 +0x187    huru/routes/share.Handler.makeGetMany(0xc4200ae1e0, 0x10)            /home/oleg/codes/huru/api/src/huru/routes/share/share.go:62 +0x108它確實確認適配器切片的長度為 2: length of adapters:2有誰知道為什么在這種情況下該類型斷言會失???沒有意義。也許我實際上并沒有檢索切片的最后一個參數之類的?有沒有更好的方法從切片中彈出最后一個參數?
查看完整描述

2 回答

?
函數式編程

TA貢獻1807條經驗 獲得超9個贊

您需要使用 .將mw.Middleware()語句的第二個參數包裝到類型中。http.Handlerhttp.HandlerFunc()


func (h Handler) makeGetMany(v Injection) http.HandlerFunc {

    return mw.Middleware(

        mw.Allow("admin"),

        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

            log.Println("now we are sending response.");

            json.NewEncoder(w).Encode(v.Share)

        }),

    )

}


查看完整回答
反對 回復 2023-05-22
?
catspeake

TA貢獻1111條經驗 獲得超0個贊

在 http 包中,?ListenAndServe具有以下簽名

func?ListenAndServe(addr?string,?handler?Handler)?error

其中Handler(ie,?http.Handler) 是一個接口

type?Handler?interface?{
????ServeHTTP(ResponseWriter,?*Request)
}

對于一個 Web 應用程序,只有一個ListenAndServe調用,因此只有一個handler,它需要處理所有訪問點,例如/url1,/url2等。如果我們從頭開始編寫handler,實現可能是struct一個圍繞數據庫句柄的自定義。它的ServeHTTP方法是檢查訪問點,然后把相應的內容寫入到ResponseWriter,比較繁瑣和雜亂。

這就是ServeMux的動機,它router在您的代碼中。它有一個ServeHTTP方法,因此它滿足http.Handler接口并可用于ListenAndServe.?此外,它還有HandleFunc處理個別接入點的方法

func?(mux?*ServeMux)?HandleFunc(pattern?string,
????????????????????????????????handler?func(ResponseWriter,?*Request))

注意這里handler不是 a?http.Handler,即它沒有ServeHTTP方法。它不必這樣做,因為它mux已經擁有ServeHTTP并且它的ServeHTTP方法可以將各個訪問點請求分派給相應的處理程序。

請注意,它還有一個Handle方法,該方法需要參數滿足http.Handler接口。與方法相比,使用起來稍微不方便HandleFunc。

func?(mux?*ServeMux)?Handle(pattern?string,?handler?Handler)

現在回到你的問題,因為你打電話router.HandleFunc,它的輸入不一定是http.Handler。因此,另一種解決方案是用作func(ResponseWriter, *Request)中間件和makeGetMany方法的返回類型。(中間件中的類型斷言也需要更新,可能還需要更新更多代碼)

@xpare 的解決方案是進行類型轉換,以便所有函數簽名匹配,即轉換func(ResponseWriter, *Request)http.HandlerFunc.?看看它是如何工作的也很有趣。

// The HandlerFunc type is an adapter to allow the use of

// ordinary functions as HTTP handlers. If f is a function

// with the appropriate signature, HandlerFunc(f) is a

// Handler that calls f.

type HandlerFunc func(ResponseWriter, *Request)


// ServeHTTP calls f(w, r).

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {

? ? f(w, r)

}

你可以看到它基本上定義了一個ServeHTTP調用自身的方法。


查看完整回答
反對 回復 2023-05-22
  • 2 回答
  • 0 關注
  • 156 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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