我正在编写一个简单的控制台游戏,并希望将玩家映射到一个符号。有两个玩家时,我的方法是这样的:
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 枚举方式?
答案 0 :(得分:1)
[我假设您的示例只是最小的,并且您的实际映射有两个以上的选项。我还假设你的意思是双向映射]
我会写一张地图:
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)
}
答案 1 :(得分:1)
除了 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
,这对于打印内容和调试很有用。
答案 2 :(得分:0)
假设您不需要任何特定映射并且玩家整数值的序列为 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')
}