我有这个实用程序:
type Handler struct{}
func (h Handler) Mount(router *mux.Router, v PeopleInjection) {
router.HandleFunc("/api/v1/people", h.makeGetMany(v)).Methods("GET")
}
上面这样称呼:
func (h Handler) makeGetMany(v PeopleInjection) http.HandlerFunc {
type RespBody struct {}
type ReqBody struct {
Handle string
}
return tc.ExtractType(
tc.TypeList{ReqBody{},RespBody{}},
func(w http.ResponseWriter, r *http.Request) {
// ...
})
}
然后
tc.ExtractType
像这样:func ExtractType(s TypeList, h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r) // <<< h is just a func right? so where does ServeHTTP come from?
}
}
我的问题是-serveHTTP方法/功能从哪里来?
h
参数不仅仅是具有此签名的功能:func(w http.ResponseWriter, r *http.Request) { ... }
那么该功能如何附加
ServeHTTP
功能呢?换句话说,我为什么打电话
h.ServeHTTP(w,r)
代替
h(w,r)
?
最佳答案
http.HandlerFunc是表示func(ResponseWriter, *Request)
的类型。http.HandlerFunc
和func(ResponseWriter, *Request)
之间的区别是:http.HandlerFunc
类型具有称为ServeHTTP()
的方法。
从source code:
// 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)
}
http.HandlerFunc()
可用于包装处理程序函数。func Something(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do something
next.ServeHTTP(w, r)
})
}
包装的处理程序将具有
http.HandlerFunc()
类型,这意味着我们将能够访问它的.ServeHTTP()
方法。还有另一种类型,称为http.Handler的接口。它具有
.ServeHTTP()
方法签名,并且必须在嵌入接口的结构上实现。type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
如您在上面的
Something()
函数上所看到的,http.Handler
类型的返回值是必需的,但是我们返回了包装在http.HandlerFunc()
中的处理程序。很好,因为http.HandlerFunc
具有满足.ServeHTTP()
接口要求的方法http.Handler
。换句话说,为什么我要调用
h.ServeHTTP(w,r)
而不是h(w,r)
?因为要继续处理传入的请求,您需要调用
.ServeHTTP()
。