Go 为什么http.HandlerFunc总是返回相同的随机数
来自新来的地鼠的问候 我有以下mux路由器设置: s、 router.HandleFunc/test,s.TestHandler s、 TestHandler: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
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应用程序中,以实现一些中间件的东西。。。