簡體   English   中英

如何在 Go 中編寫雙向映射?

[英]How to write a bidirectional mapping in Go?

我正在編寫一個簡單的控制台游戲,並希望將玩家映射到一個符號。 對於兩個玩家,我的方法是這樣的:

func playerToString(p player) string {
    if p == 0 {
        return "X"
    }
    return "O"
}

func stringToPlayer(s string) player {
    if s == "X" {
        return 0
    }
    return 1
}

當然,您也可以將其寫為兩個映射,將 int 映射到 string,將 string 映射到 int。 上述方法和地圖方法似乎都容易出錯。 有沒有更慣用的方式來寫這個? 也許一些非iota枚舉方式?

[我假設您的示例只是最小的,並且您的實際映射有兩個以上的選項。 我還假設您的意思是雙向映射]

我會寫一張地圖:

var player2string = map[int]string{
  0: "0",
  1: "X",
  // etc...
}

然后將創建一個函數來以編程方式填充不同的地圖string2player 像這樣的東西:

var player2string = map[int]string{
    0: "0",
    1: "X",
    // etc...
}

var string2player map[string]int = convertMap(player2string)

func convertMap(m map[int]string) map[string]int {
    inv := make(map[string]int)
    for k, v := range m {
        inv[v] = k
    }
    return inv

}

func main() {
    fmt.Println(player2string)
    fmt.Println(string2player)
}

在 Go 游樂場上試試

除了 Eli 的回答之外,您還可以進行另外兩項更改。 您可以使 to-symbol 函數成為player類型的方法。 並且因為玩家值是整數(從零開始的順序),您可以使用切片而不是映射來存儲整數到符號的映射——存儲和查找的效率更高一些。

type player int

var playerSymbols = []string{"X", "O", "A", "B", "C", "D", "E", "F", "G", "H"}

func (p player) Symbol() string {
    if int(p) < 0 || int(p) >= len(playerSymbols) {
        return "?" // or panic?
    }
    return playerSymbols[p]
}

這個方法簽名甚至可以是String() string所以它是一個fmt.Stringer ,這對於打印內容和調試很有用。

假設您不需要任何特定的映射並且玩家整數值的序列為 0,1,2,3,...,25,您可以直接生成玩家符號而不使用地圖,如下面的代碼片段所示:-

type player int

func ToSymbol(p player) string {
    return fmt.Sprintf("%c", 'A' + p)
}

func ToPlayer(symbol string) player {
    return player([]rune(symbol)[0] - 'A')
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM