登录
首页 >  Golang >  Go问答

在循环中声明处理程序并将其分配给 ServeMux 不起作用

来源:stackoverflow

时间:2024-04-11 22:39:29 247浏览 收藏

积累知识,胜过积蓄金银!毕竟在Golang开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《在循环中声明处理程序并将其分配给 ServeMux 不起作用》,就带大家讲解一下知识点,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~

问题内容

我有以下代码,但它没有按预期工作。具体来说,对任何端点的所有请求都将作为对 /banana/auth/banana/description 端点的请求进行处理。

type route struct {
    authroute        string
    descriptionroute string
}

var routes = [2]route{
    {
        authroute:        "/apple/auth",
        descriptionroute: "/apple/description",
    },
    {
        authroute:        "/banana/auth",
        descriptionroute: "/banana/description",
    },
}

// ...
sm := http.newservemux()

for i, authserverconfig := range authserverconfigs {
    authhandler := http.handlerfunc(func(w http.responsewriter, r *http.request) {
        authserverconfig.auth(w, r)
    }
    sm.handle(routes[i].authroute, authhandler)

    descriptionhandler := http.handlerfunc(func(w http.responsewriter, r *http.request) {
        authserverconfig.servedescription(w, r)
    }
    sm.handle(routes[i].descriptionroute, descriptionhandler)
}

server := &http.server{
    // ...
    handler: sm,
    // ...
}
server.listenandserve()

当我继续用这些语句替换 for 循环时,它完全按照我想要的方式工作:

    authHandlerApple := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        authServerConfig.Auth(w, r)
    }
    sm.Handle(routes[0].AuthRoute, authHandlerApple)

    descriptionHandlerApple := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        authServerConfig.ServeDescription(w, r)
    }
    sm.Handle(routes[0].DescriptionRoute, descriptionHandlerApple)

    authHandlerBanana := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        authServerConfig.Auth(w, r)
    }
    sm.Handle(routes[1].AuthRoute, authHandlerBanana)

    descriptionHandlerBanana := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        authServerConfig.ServeDescription(w, r)
    }
    sm.Handle(routes[1].DescriptionRoute, descriptionHandlerBanana)

问题是,我最初做错了什么以及如何避免编写第二个示例中那样的笨重代码?


正确答案


根据 FAQ - What happens with closures running as goroutines,每个闭包在 for 循环中共享单个变量 authserverconfig 。要修复它,只需在循环中添加 authserverconfig := authserverconfig

for i, authServerConfig := range authServerConfigs {
     authServerConfig := authServerConfig

    authHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        authServerConfig.Auth(w, r)
    })
    sm.Handle(routes[i].AuthRoute, authHandler)

    descriptionHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        authServerConfig.ServeDescription(w, r)
    })
    sm.Handle(routes[i].DescriptionRoute, descriptionHandler)
}

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>