来自新手地鼠的问候!
我有以下多路复用路由器设置:
s.router.HandleFunc("/test", s.TestHandler())
s.TestHandler:
func (s *server) TestHandler() http.HandlerFunc {
rnd := rand.Intn(100)
response := struct {
RND int `json:"rnd"`
}{
rnd,
}
return func(w http.ResponseWriter, r *http.Request) {
s.respond(w, r, 200, response)
return
}
}
Run Code Online (Sandbox Code Playgroud)
辅助方法 s.respond:
func (s *server) respond(w http.ResponseWriter, r *http.Request, code int, data interface{}) {
w.WriteHeader(code)
if data != nil {
json.NewEncoder(w).Encode(data)
}
}
Run Code Online (Sandbox Code Playgroud)
问题是当我发出 GET /test 时,除非重新启动应用程序,否则我会看到相同的数字。
我确定我做错了什么,如果有人指出我的错,我将不胜感激。
函数字面量是闭包:它们可以引用在周围函数中定义的变量。然后这些变量在周围的函数和函数字面量之间共享,只要它们可访问,它们就会存在。
TestHandler()产生一个单一随机值,然后返回一个函数文本,即闭合,使用该已生成的值来发送时,它是由路由器执行的响应。
但是,无论何时调用闭包,闭包的周围函数都不会也没有理由与闭包一起执行。周围的函数仅在它本身被调用时才执行,例如当您在其中注册处理程序时s.router.HandleFunc("/test", s.TestHandler())。
因此,在提供的代码中,rand.Intn您中的函数只TestHandler被调用一次,而不是像您认为的那样,每次您通过请求访问服务器时都不会调用它。
要解决这个问题,只需将生成随机值的代码移动一个级别:
func (s *server) TestHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
rnd := rand.Intn(100)
response := struct {
RND int `json:"rnd"`
}{
rnd,
}
s.respond(w, r, 200, response)
}
}
Run Code Online (Sandbox Code Playgroud)