例子
先看一个简单的例子:
package main
import (
"fmt"
"net/http"
)
type HelloHandler struct{}
func (h HelloHandler) ServeHTTP (w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello Handler!")
}
func hello (w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
}
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
}
helloHandler := HelloHandler{}
http.Handle("/hello1", helloHandler)
http.HandleFunc("/hello2", hello)
server.ListenAndServe()
}
上述代码启动了一个 http 服务器,监听 8080 端口,分别实现了 /hello1
和 /hello2
两个路由。实现这两个路由的方法有点不同,一个使用 http.Handle
,另一个使用 http.HandleFunc
,下面来看看这两个之间的区别;
http.Handle
首先,简单分析一下 http.Handle(pattern string, handler Handler)
,http.Handle(pattern string, handler Handler)
接收两个参数,一个是路由匹配的字符串,另外一个是 Handler
类型的值:
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
然后由继续调用 DefaultServeMux.Handle(pattern string, handler Handler)
,该函数接收的参数与上面的函数一样:
func (mux *ServeMux) Handle(pattern string, handler Handler) {
...
}
这个 Handler
类型是什么呢,其实它就是一个接口,包含一个 ServeHttp()
的方法:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
所以,传入 http.Handle(pattern string, handler Handler)
第二个参数必须实现 ServeHTTP
这个方法,当接收到一个匹配路由的请求时,会调用该方法。
http.HandleFunc
该方法接收两个参数,一个是路由匹配的字符串,另外一个是 func(ResponseWriter, *Request)
类型的函数:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
然后继续调用 DefaultServeMux.HandleFunc(pattern, handler)
:
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
mux.Handle(pattern, HandlerFunc(handler))
}
可以看到,这里把 handler
转换成了 HandlerFunc
类型,而 HandlerFunc
类型则如下所示:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
该类型实现了 ServeHTTP
接口,所以其也可以转换成 Handler
类型,接下来调用 mux.Handle(pattern string, handler Handler)
就跟 http.Handle
的流程是一样的了。