http.Handle(处理程序或处理程序函数)

huangapple go评论75阅读模式
英文:

http.Handle(Handler or HandlerFunc)

问题

以下是翻译好的部分:

handle()函数被传递一个与http.HandlerFunc类型匹配的函数,或者一个实现了http.Handler接口的类型。

英文:

How is the following function implemented?

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() is passed either a function which matches the type of http.HandlerFunc or a type which implements the http.Handler interface.

答案1

得分: 11

代替使用反射,我会这样做:

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:
        // 错误处理
    }
    http.Handle(pattern, h)
}
英文:

Instead of resorting to reflection, I would do it this way:

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

答案2

得分: 2

首先,我们需要介绍Java/C#术语中的"reflections",以及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是一个不同的类型
    // func(http.ResponseWriter, *http.Request),但我们可以这样做
    // 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)
}
英文:

First we need to introduce the term "reflections" in Java/C#'s terminology, RTTI in C++'s terminology. It's quite simple actually. The compiler keeps data to find out what is the type of an instance var i SomeType during runtime. Go supports reflection, and that's how it finds out what's the type of handler during runtime.

The handle function uses the reflection. A crude example

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

huangapple
  • 本文由 发表于 2011年6月16日 07:13:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/6365535.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定