【问题标题】:Storing state in Go在 Go 中存储状态
【发布时间】:2014-10-02 22:07:27
【问题描述】:

我正在用 Go 编写一个简单的程序作为学习语言的练习。该程序是一个游戏玩家:它exec.Commands 是一个基于文本的游戏,然后通过StdinPipe/StdoutPipe 与之通信。在闲逛并阅读了大量在线文档后,我设法让骨架工作了——相当于 Hello World,我已经建立了双向通信,并且可以处理程序终止等错误。

现在我正在尝试编写实际的游戏 AI 代码。因为我的目的是学习这门语言,所以我对风格非常谨慎——我不只是想用 Go 编写 C(或其他语言)。

程序中明显的分工(一旦完成所有设置)分为两部分。首先,程序查看当前状态并决定应该向游戏发出什么命令。其次,程序查看返回的数据并相应地更新状态。 (是的,这是一个简单的游戏——它等待输入然后响应,不存在时间问题。)

我不确定这些状态信息应该放在哪里。将它全部转储到全局范围内感觉是错误的,并且制作一个巨大的单例对象似乎更糟(而且 Go 并不是特别 OO)。在任何情况下,我都不想让函数传递并返回 20 多个变量。

一般建议很好,但我最感兴趣的是惯用的 Go 语言。根据要求,我可以共享代码,但我认为这不会有帮助。

【问题讨论】:

    标签: architecture go coding-style global-variables information-hiding


    【解决方案1】:

    我喜欢为此目的使用包。

    简单的例子:

    package foo
    
    func Incr() {
        f.incr()
    }
    
    func Count() int {
        return f.count()
    }
    
    type foo struct {
        sync.RWMutex
        count int
    }
    
    func (f *foo) incr() {
        f.Lock()
        f.count++
        f.Unlock()
    }
    
    func (f *foo) count() int {
        f.RLock()
        defer f.RUnlock()
        return f.count
    }
    
    var f = &foo{}
    

    这个包可以被导入任何其他包并保持状态。我添加了 sync.RWMutex 以防止任何竞争条件。这使您可以完全控制 foo 的状态如何被访问和很好地包含。

    【讨论】:

    • 谢谢。让我确保我理解你的建议:我创建了一个 struct 来保存我所有的状态变量,然后将它实例化为一个全局对象,这样我就可以在我的更新函数中检查和修改状态。正确的? (当然我为你 +1 了。)
    • @Charles 正确。您可以在结构上存储您想要的任何状态,并根据需要向该结构添加方法。这种方法的好处是您可以完全控制访问并轻松将状态导入其他包。 Go 的 net/http 包采用与 HandlerFunc 和 Handler 方法类似的方法,允许您在多个包中添加 http 处理程序。
    • @tommywild 你能详细说明一下吗?添加 foo_test 并测试包中的任何内容非常容易。您还可以使用导出的方法轻松测试上述功能。
    • @tommywild 我明白你在说什么。我编辑了答案,所以 foo 有一个 incr 和 count 方法,这将允许独立于 f 的状态测试 foo。
    • @tommywild 我暂时删除了这个答案,想了一会儿,现在正在取消删除它。我的理性:在游戏(或大多数程序)中,您将需要某种方式来维持状态。上述方法允许线程安全地访问游戏状态,并允许程序的任何部分轻松访问所述状态,而无需将状态传递给每个函数。我认为应该谨慎使用这种方法,但一定程度的实用主义会有很长的路要走。
    【解决方案2】:

    Go 确实启用了style of OO programming

    为游戏状态创建一个结构类型。在你的程序中传递一个指向这种类型的值的指针,或者如果这种事情不打扰你,则将指针存储在包级变量中。根据需要在此类型上实施方法。考虑将其放入自己的包中以进行更好的封装。

    【讨论】:

    • 感谢您的回答。如果您不介意,我会等到明天接受答案——我仍在考虑哪种解决方案是最好的。 (同时 +1。)
    猜你喜欢
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多