新手gopher的问候!
我有以下多路复用器路由器设置:
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
}
}
Helper方法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)
}
}
问题是当我发出GET / test时,除非重新启动应用程序,否则我看到的数字相同。
我确定我做错了,如果有人请指出我的错,我将不胜感激。
答案 0 :(得分:5)
函数文字是 closures :它们可以引用在中定义的变量 周围的功能。然后,这些变量将在 周围的函数和函数文字,它们作为 只要它们可以访问。
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)
}
}