我有这个实用程序:
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)
?
答案 0 :(得分:5)
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()
。