为了账号安全,请及时绑定邮箱和手机立即绑定

httprouterhttp.HandlerFunc() 是如何工作的?

httprouterhttp.HandlerFunc() 是如何工作的?

Go
开满天机 2022-12-26 10:16:53
我正在学习 Go,目前正在尝试了解julienschmidt 的 httprouterhttp路由器的实际工作原理和工作原理。特别是 router.HandlerFunc() 的工作原理。Go 的 http 包:http.Handler:处理程序是一个接口。具有相同方法签名的任何类型,即 ServeHTTP(w,r) 实现一个处理程序。http.Handle: http.Handle 是一个有两个参数的函数。1) 匹配请求路径的字符串, 2) Handler,调用它的 ServeHTTP() 方法。http.HandlerFunc: 具有函数签名 (ResponseWriter, *Request) 和它自己的 ServeHTTP(w,r) 方法的自定义函数类型,满足 http.Handler 接口。现在,如果我需要使用一个函数,例如。Bar(ResponseWriter, *Request) 满足作为 HandlerFunc,在 http.Handle 中,我键入 caste/covert 函数到 http.HandlerFunc,然后在 http.Handle 中使用它。像这样:func Bar(w http.ResponseWriter, r *http.Request) {     w.Write([]byte("My bar func response")) } ... mf := http.HandlerFunc(Bar) http.Handle("/path", mf)查看http.HandleFunc 源代码,这就是 http.HandleFunc() 的工作原理。它需要一个函数作为 (w ResponseWriter, r *Request) 的签名并键入该函数。像这样:func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {    if handler == nil {        panic("http: nil handler")     }     mux.Handle(pattern, HandlerFunc(handler)) }julienschmidt 的 httprouterhttp查看router.HandlerFunc() 的源代码func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc) {     r.Handler(method, path, handler) }它不像 http.HandleFunc() 那样期望具有适当签名(ResponseWriter、*Request)的函数,而是期望一个 http.HandlerFunc。同样没有类型转换/将函数转换为 HandlerFunc 类型,它只是将函数传递给另一个函数 router.Handler(method, path string, handler http.Handler),它再次需要一个 Handler。所以我可以毫无问题地执行这段代码:router.HandlerFunc(http.MethodPost, "/path", Bar) // Bar is not type casted/converted to a HandlerFunc我可以理解将 Bar 类型转换为 HandlerFunc,然后将其传递给 router.HandlerFunc()。您能否消除我的一些疑问:如果不将 Bar() 类型转换为 HandlerFunc,如何满足作为 HandlerFunc 类型到 router.HandlerFunc() 的要求?如果 router.Handler() 需要一个 http.Handler 类型,为什么没有类型转换为 http.HandlerFunc 的 Bar() 满足 router.Handler() 的处理程序?我错过了什么?
查看完整描述

2 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

  1. “如果不将 Bar() 类型转换为 HandlerFunc,如何满足作为 HandlerFunc 类型到 router.HandlerFunc() 的要求?”

表达方式

router.HandlerFunc(http.MethodPost, "/path", Bar)

符合Assignability规则:

V并且T具有相同的基础类型,并且至少有一个V或者T不是命名类型。

Bar函数的类型和类型http.HandlerFunc具有相同的底层类型,并且Bar类型没有命名。因此,您可以将(分配)Bar作为handler参数传递给httprouter.Router.HandlerFunc而无需显式转换


  1. “如果 router.Handler() 需要一个 http.Handler 类型,为什么没有类型转换为 http.HandlerFunc 的 Bar() 会满足 router.Handler() 的处理程序?”

在下面的方法定义中

func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc) {
    r.Handler(method, path, handler)
}

没有,只有类型为的参数 并且该类型确实实现了接口。因此,该声明是完全合法的。Barhandler http.HandlerFunchttp.Handlerr.Handler(method, path, handler)


  1. “我错过了什么?”

看上面。


查看完整回答
反对 回复 2022-12-26
?
动漫人物

TA贡献1815条经验 获得超10个赞

查看 HandlerFunc 的定义

type HandlerFunc func(ResponseWriter, *Request)

以及您的功能签名

(w http.ResponseWriter, r *http.Request)

你不需要在这里转换。


查看完整回答
反对 回复 2022-12-26
  • 2 回答
  • 0 关注
  • 97 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信