0

我正在编写一个简单的Go程序来学习语言。该程序是一个游戏玩家:它exec.Command是一个基于文本的游戏,然后通过StdinPipe/StdoutPipe与它进行通信。在一些鬼混和阅读了很多在线文档后,我设法使骨架工作 - 相当于Hello World,我建立了双向通信并可以处理程序终止等错误。在Go中存储状态

现在我正在尝试编写实际的游戏AI代码。由于我的目的是学习语言,因此我试图对样式非常小心 - 我不只是想在Go中编写C语言(或其他语言)。

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

我不知道这个状态信息应该去哪里。把它全部扔进全球范围感觉不对,并且制造一个巨大的单身物体似乎更糟糕(而Go不是特别的OO)。无论如何,我不想让这些函数传递并返回20多个变量。

一般建议是好的,但我最关心什么是适合Go的惯用。根据要求我可以分享代码,但我认为这不会有帮助。

回答

1

Go确实启用了style of OO programming

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

+1

谢谢你的回答。如果你不介意我会等到明天才能接受答案 - 我仍然在研究什么解决方案是最好的。 (在此期间+1。) – Charles 2014-10-03 02:47:40

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的状态如何被访问并且被很好地包含。

+0

谢谢。让我确定我理解你的建议:我创建一个'struct'来存放我所有的状态变量,然后将它实例化为一个全局对象,这样我就可以在更新函数中检查和修改状态。正确? (当然,我为你+1了。) – Charles 2014-10-03 02:48:57

+0

@Charles正确。如果你喜欢,你可以在结构上存储你想要的任何状态,并将方法添加到该结构中。这种方法的积极意义在于您可以完全控制访问并轻松将状态导入其他软件包。 Go的net/http包采用HandlerFunc和Handler方法的类似方法,允许您在多个包中添加http处理程序。 – jmaloney 2014-10-03 03:15:56

+0

@tommywild你能详细说明吗?在包中添加foo_test并测试任何东西非常简单。您还可以使用导出的方法轻松测试上述功能。 – jmaloney 2014-10-03 13:48:02