为什么http.HandlerFunc总是返回相同的随机数?

问题描述 投票:0回答:1

新手gopher的问候!

我有以下的mux路由器设置。

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
    }
}

辅助方法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测试时,我看到同样的数字,除非应用程序被重新启动。

我确定我做错了什么,如果有人能指出我的错误,我将感激不尽。

go gorilla
1个回答
5
投票

函数字面意义

函数字面意思是 关闭:它们可能指的是一个周围函数中定义的变量。这些变量在周围函数和函数文字之间共享,只要它们可以被访问,它们就可以继续存在。


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)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.