我正在用 Go 编写一个 CMS,并且有一个 session 类型(用户 ID、要呈现的页面内容等)。理想情况下,我希望该类型是一个全局变量,这样我就不必通过所有嵌套函数传播它,但是拥有一个这样的全局变量显然意味着每个新 session 都会覆盖它的前任,这不必要地说,将是一个史诗般的失败。
一些语言提供了一种在线程中拥有全局变量的方法,这些全局变量被保存在该线程中(即,该全局变量的值在该线程中被沙盒化)。虽然我知道 Goroutines 不是线程,但我只是想知道是否有类似的方法可供我使用,或者我是否必须通过各种嵌套例程向下传递我的 session 类型的本地指针。
我猜 channel 不会这样做?据我所知(如果我在这里错了请纠正我),但它们基本上只是一种共享全局变量的安全方式?
编辑:我忘记了这个问题!无论如何,为任何好奇的人提供更新。这个问题是我刚接触 Go 的时候写回来的,CMS 基本上是我的第一个项目。我来自熟悉 POSIX 线程的 C 背景,但我很快意识到一种更好的方法是在模式功能设计中编写代码, session 对象作为函数参数中的指针传递。这为我提供了我所追求的上下文相关的本地范围,同时也最大限度地减少了我正在复制的数据量。然而,作为一个有 7 年历史的项目,并且是在我开始过渡到 Go 的时候,可以公平地说,这个项目无论如何都可以进行重大重写,因为它犯了很多错误。不过,这是另一天的问题 - 目前它有效,我还有足够多的其他项目在进行中。
最佳答案
你会想要使用类似Context
的东西:
http://blog.golang.org/context
基本上,该模式是为您想做的每个独特的事情创建一个Context
。 (在你的情况下是一个网络请求。)使用 context.WithValue
在上下文中嵌入多个变量。然后总是将它作为第一个参数传递给在其他 goroutine 中做进一步工作的其他方法。
从上下文中获取您需要的变量是从任何 goroutine 中调用 context.Value
的问题。从上面的链接:
A
Context
is safe for simultaneous use by multiple goroutines. Code can pass a singleContext
to any number of goroutines and cancel thatContext
to signal all of them.
我有一个实现,其中我明确地将变量作为方法参数发送,我发现使用上下文嵌入这些变量可以显着清理我的代码。
使用 Context
也有帮助,因为它提供了使用 channel 、select
和称为“完成 channel ”的概念来结束长时间运行的任务的方法。请参阅这篇文章以获得出色的基本审查和实现:
http://blog.golang.org/pipelines
我建议先阅读管道文章,了解如何管理 goroutine 之间的通信,然后再阅读上下文文章,更好地了解如何升级并开始嵌入变量以传递。
祝你好运!
关于没有 goroutines 覆盖的 Go lang 全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15768970/