【发布时间】:2016-08-13 18:29:25
【问题描述】:
我知道有一些关于这个问题的问题和帖子/文章,但从我的新手看来,不完全是。 问题是,我有一个主程序监听一个端口并将调用重定向到一个特定的处理程序。典型结构:
func main() {
http.HandleFunc("/something", specificHandler)
http.ListenAndServe(":8080", nil)
}
处理程序类似于:
func specificHandler(w http.ResponseWriter, r *http.Request) {
somepackage.foo()
}
然后somepackage,其中包含函数foo,有一些全局变量,主要是因为它们是函数共享所需要的(例如,当使用实现的优先级队列时)使用容器/堆,它将从全局距离矩阵中获取交换函数中的优先级,这当然是可变的)。还有很多其他的例子。总之,全局变量...
如您所见,问题在于,这些变量在对处理程序的所有调用之间共享。这很糟糕。
我该如何真正解决这个问题?一定有一种简单的方法可以做到,我还没有做到,因为它看起来很平常......
提前致谢。
编辑
为了更清楚。例如,在我的 A* 包中,我有以下全局变量:
var openVerticesAS PriorityQueueAStar
// which vertices are closed
var closedVertices map[int]bool
// which vertices are currently open
var openVertices map[int]bool
// cost from start to node
var gScore map[int]float64
// cost from start to end, passing by node i (g+h)
var fScore map[int]float64
那么,PriorityQueueAStar实现如下:
type PriorityQueueAStar []int // rel id
func (pq PriorityQueueAStar) Len() int { return len(pq) }
func (pq PriorityQueueAStar) Empty() bool { return len(pq) == 0 }
func (pq PriorityQueueAStar) Less(i, j int) bool {
return fScore[pq[i]] < fScore[pq[j]]
}
func (pq PriorityQueueAStar) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
}
func (pq *PriorityQueueAStar) Push(x interface{}) {
*pq = append(*pq, x.(int))
}
func (pq *PriorityQueueAStar) Pop() interface{} {
old := *pq
n := len(old)
rel := old[n-1]
*pq = old[0 : n-1]
return rel
}
func (pq PriorityQueueAStar) Top() interface{} {
return pq[0]
}
那么问题是,我如何在不将所有这些映射都作为全局变量的情况下继续这样做?如果它们是结构的一部分,我如何从优先队列函数中访问结构?
【问题讨论】:
-
您认识到您在不同调用之间修改了变量这一事实表明这是设计。听起来你想要某种容器。您需要设计一个结构以满足您的需求,并将该结构传递给 somepackage 中对您的函数的调用。
-
是的,这听起来不错,或者为整个包创建一个结构并让它包含变量。但是堆接口中的像 Less(i, j int) 这样的函数呢?这些将需要访问该结构,我看不到将其传递给他们的方法...
-
查看频道chan,他们解决了很多与共享内存相关的问题。
-
你不需要传递函数。您将定义一个实现排序功能的结构类型
。然后你可以在任何你需要的地方做 foo.Sort() 。 @jcasado94 如果您可以提供您正在使用的数据类型,这可能会帮助我们提出一个好的解决方案。查看stackoverflow.com/a/28999886/4746361 开始使用。 -
这个包基本上运行了一些寻路算法,并且必须用路径来回答。因此变量主要是实现容器/堆接口的优先级队列和开/关顶点的映射等,当然还有一个Graph struct...
标签: go global-variables httphandler