簡體   English   中英

http.Handle(Handler或HandlerFunc)

[英]http.Handle(Handler or HandlerFunc)

如何實現以下功能?

func handle(pattern string, handler interface{}) {
    // ... what goes here? ...
    http.Handle(pattern, ?)
}

handle("/foo", func(w http.ResponseWriter, r http.Request) { io.WriteString(w, "foo") }
handle("/bar", BarHandler{})

handle()傳遞一個匹配http.HandlerFunc類型的函數或一個實現http.Handler接口的類型。

我不是采用反思,而是這樣做:

func handle(pattern string, handler interface{}) {
    var h http.Handler
    switch handler := handler.(type) {
    case http.Handler:
        h = handler
    case func(http.ResponseWriter, *http.Request):
        h = http.HandlerFunc(handler)
    default:
        // error
    }
    http.Handle(pattern, h)
}

首先,我們需要在Java / C#的術語中引入術語“反射”,在C ++的術語中引入RTTI。 實際上這很簡單。 編譯器保留數據以在運行時期間找出實例var i SomeType的類型。 Go支持反射,這就是它如何在運行時找出handler的類型。

handle函數使用反射。 一個粗略的例子

package main
import ("reflect";"http")
type fakeHandler struct{}
func (frw *fakeHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}

func handle(pattern string, handler interface{}) {
    handlerInterface := reflect.TypeOf(new(http.Handler)).Elem()
    handlerFunction  := reflect.TypeOf(new(http.HandlerFunc)).Elem()
    t := reflect.TypeOf(handler)
    if t.Implements(handlerInterface) {fmt.Println("http.Handler")}
    //http.HandlerFunc is a different type than
    // func(http.ResponseWriter, *http.Request), but we can do
    // var hf HandlerFunc = func(http.ResponseWriter, *http.Request){}
    if t.AssignableTo(handlerFunction) {fmt.Println("http.HandleFunc")}
}
func f(http.ResponseWriter, *http.Request) {}
func main() {
    handle("",&fakeHandler{})
    handle("",f)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM