在Go中存储状态

时间:2014-10-02 22:07:27

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

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

现在我正在尝试编写实际的游戏AI代码。因为我的目的是学习语言,所以我试着非常小心风格 - 我不只是想在Go中写C(或其他语言)。

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

我不确定这个州的信息应该去哪里。把它全部倾注到全局范围感觉是错误的,并且制作一个庞大的单例对象似乎更糟糕(并且Go不是特别OO)。在任何情况下,我都不希望函数通过并返回20+个变量。

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

2 个答案:

答案 0 :(得分:1)

Go确实启用了style of OO programming

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

答案 1 :(得分: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的状态如何被访问并且包含得很好。