在 Golang 中将全局变量与 Http 处理程序一起使用

我知道有一些关于这个问题的问题和帖子/文章,但从我新手的角度来看,并不完全如此。问题是,我有一个主程序监听端口并将调用重定向到特定的处理程序。典型结构:


func main() {

    http.HandleFunc("/something", specificHandler)

    http.ListenAndServe(":8080", nil)

}

处理程序类似于:


func specificHandler(w http.ResponseWriter, r *http.Request) {

    somepackage.foo()

}

然后somepackage,其中包含函数foo,有一些全局变量,基本上是因为函数需要共享它们(例如,当使用由容器/堆实现的优先级队列时,它将从 Swap 函数中获取优先级全局距离矩阵,当然是可变的)。以及许多其他例子。总之,全局变量...


问题是,正如您可能看到的,这些变量在对处理程序的所有调用之间共享。这很糟糕。


我怎样才能真正解决这个问题?必须有一种简单的方法来做到这一点,我还没有,因为它看起来很平常......


提前致谢。


翻阅古今
浏览 208回答 1
1回答

慕容708150

当您的处理程序需要一个变量时,通常意味着您应该实现Handler接口而不是提供HandlerFunc函数。这是一个不好的例子(使用全局变量):var globalThing stringfunc specificHandler(w http.ResponseWriter, r *http.Request) {    w.Write(globalConfigThing)}func main() {    globalThing = "Hello world!"    http.HandleFunc("/something", specificHandler)    http.ListenAndServe(":8080", nil)}这是一个更好的例子(不使用全局变量):type specificHandler struct {    Thing string}func (h *specificHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {    w.Write(h.Thing)}func main() {    http.Handle("/something", &specificHandler{Thing: "Hello world!"})    http.ListenAndServe(":8080", nil)}如您所见,aHandler可以封装变量。为了完整性,另一种方法是使用函数闭包。这适用于一次性处理程序,但不可重用,并且更难为其编写单元测试。func main() {    scopedThing := "Hello world!"    http.HandleFunc("/something", func (w http.ResponseWriter, r *http.Request) {        w.Write(scopedThing)    })    http.ListenAndServe(":8080", nil)}正确完成后,您现在可以somepackage通过将全局变量作为参数等传递来避免包中的全局变量。编辑:例如,您可以使用包中的几个PriorityQueueAStar字段定义处理程序结构somepackage:type specificHandler struct {    QueueA somepackage.PriorityQueueAStar    QueueB somepackage.PriorityQueueAStar    QueueC somepackage.PriorityQueueAStar}func (h *specificHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {    h.QueueA.Push(h.QueueB.Pop)    h.QueueB.Push(h.QueueC.Pop)    w.Write([]byte("Queues pushed and popped"))}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go