Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 为什么http.HandlerFunc总是返回相同的随机数_Go_Gorilla - Fatal编程技术网

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

Go 为什么http.HandlerFunc总是返回相同的随机数,go,gorilla,Go,Gorilla,来自新来的地鼠的问候 我有以下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 fu

来自新来的地鼠的问候

我有以下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/test时,我会看到相同的数字,除非重新启动应用程序

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

函数文字是闭包:它们可能引用在中定义的变量 周围的功能。然后,这些变量在 围绕函数和函数文字,它们作为 只要它们是可访问的

TestHandler生成一个随机值,然后返回一个函数文本,即闭包,该闭包在路由器执行响应时使用已生成的值发送响应

但是,每当调用闭包时,闭包的周围函数不会也没有理由与闭包一起执行。只有在调用周围函数时,才会执行该函数,例如在s.router.HandleFunc/test中注册处理程序时,例如在s.TestHandler中

因此,在提供的代码中,TestHandler中的rand.Intn函数只被调用一次,而不是像您认为的那样,每次您通过请求访问服务器时都会被调用

要解决此问题,只需将生成代码的随机值移动到以下级别:

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)
    }
}
函数文字是闭包:它们可能引用在中定义的变量 周围的功能。然后,这些变量在 围绕函数和函数文字,它们作为 只要它们是可访问的

TestHandler生成一个随机值,然后返回一个函数文本,即闭包,该闭包在路由器执行响应时使用已生成的值发送响应

但是,每当调用闭包时,闭包的周围函数不会也没有理由与闭包一起执行。只有在调用周围函数时,才会执行该函数,例如在s.router.HandleFunc/test中注册处理程序时,例如在s.TestHandler中

因此,在提供的代码中,TestHandler中的rand.Intn函数只被调用一次,而不是像您认为的那样,每次您通过请求访问服务器时都会被调用

要解决此问题,只需将生成代码的随机值移动到以下级别:

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

形式上:因为您不生成随机数,所以您生成一个伪随机数。这一代数字是确定性的,只是数字序列看起来有点随机。@Volker-这是真的,但在OP的问题中,这是因为他们的handlerfunc不包含对rand.Intn的调用,它包含已经生成的数字。形式上:因为你不生成随机数,你生成的是伪随机数。这一代数字是确定的,只是数字序列看起来有点随机。@Volker-没错,但在OP的问题中,这是因为他们的handlerfunc不包括对rand.Intn的调用,它包括已经生成的数字。谢谢,先生!我还必须了解何时使用和何时不使用闭包用例目前对我来说还不是100%清楚=@MichaelC Yes,在这种情况下,让TestHandler返回一个处理程序比让TestHandler只是一个处理程序没有真正的好处。然而,有一些情况下,您可能实际上只想做一次XYZ,然后返回返回的闭包,重新使用XYZ的结果。@ MichaelC考虑这个,在这里您看到模板的解析只做一次,然后模板被返回的闭包重复使用。这节省了大量cpu周期,如果解析阶段在闭包中,这些cpu周期将被不必要地浪费。@MichaelC许多Go处理程序特定的中间件也使用闭包实现,如果您继续在Go中编程web服务器,您很快就会遇到这些情况。此外,下面的链接可能有助于更清楚地说明如何/何时使用它们:是的,我将继续使用go编写web应用程序,我喜欢它,而不是我偶尔遇到的PHP。谢谢你们为我指明了正确的方向,我发现闭包可以潜在地用于web应用程序中,以实现一些中间件功能……谢谢你们,先生!我还必须了解何时使用和何时不使用闭包用例目前对我来说还不是100%清楚=@MichaelC Yes,在这种情况下,让TestHandler返回一个处理程序比让TestHandler只是一个处理程序没有真正的好处。然而,有一些情况下,您可能实际上只想做一次XYZ,然后返回返回的闭包,重新使用XYZ的结果。@ MichaelC考虑这个,在这里您看到模板的解析只做一次,然后模板被返回的闭包重复使用。这节省了大量cpu周期,否则将是u
n如果解析阶段在闭包中,那将是不必要的浪费。@MichaelC许多Go处理程序特定的中间件也是使用闭包实现的,如果您继续在Go中编程web服务器,您很快就会遇到这些问题。此外,下面的链接可能有助于更清楚地说明如何/何时使用它们:是的,我将继续使用go编写web应用程序,我喜欢它,而不是我偶尔遇到的PHP。谢谢你们给我指明了正确的方向,我看到闭包可以潜在地用于web应用程序中,以实现一些中间件的东西。。。