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