在 Go 中,你可以用for和下标来遍历slice,也可以使用range。range还允许你遍历map。
每次迭代都会返回两个值:下标/键,以及该下标/键对应元素的副本。
小菜一碟,遍历slice时,顺序和预期一致。
xi := []int{10, 20, 30}
for i, x := range xi {
fmt.Println(i, x)
}
// outputs:
// 0, 10
// 1, 20
// 2, 30
遍历map会带来一个新问题。
现在的顺序是随机的。
hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
fmt.Println(k, v)
}
// outputs, for example:
// 99 20
// 999 30
// 9 10
上面的输出看起来可能不对,因为人们会以为在声明 map 时最先出现的键值对9 10应该最先打印,而不是最后一个。
然而,map 天生就是无序的,并不存在第一个或最后一个键值对。
因此,在遍历 map 的条目时,访问条目的顺序是随机的,不会遵循任何特定规律。
这意味着上面的输出是有可能的,但你自己运行这段代码时得到的结果可能不一样。
想了解更多,请参阅 Go 语言规范:range 子句。
在 Go 中,未使用的变量会在构建时引发错误。 有时你只需要值,就像第一个例子那样:
xi := []int{10, 20, 30}
for i, x := range xi {
fmt.Println(x)
}
// Go build failed: i declared but not used
你可以用_替换i,这告诉编译器我们不使用那个值:
xi := []int{10, 20, 30}
for _, x := range xi {
fmt.Println(x)
}
// outputs:
// 10
// 20
// 30
如果你只想打印下标,可以用_替换x,或者干脆省略声明:
xi := []int{10, 20, 30}
// for i, _ := range xi {
for i := range xi {
fmt.Println(i)
}
// outputs:
// 0
// 1
// 2
类型定义会创建一个新的具名类型,它与其他任何类型都不相同,哪怕另一个类型的底层类型和它一样。
type File []bool
这里的File指的是棋盘上的一条竖列,通常用 A 到 H 标注。
这一列中的每个格子都用一个布尔值表示,标记它是否被占据。
既然File已经定义好了,我们就可以在其他定义里使用它:
type Chessboard map[string]File
board := Chessboard{
"A": File{true, false, true},
"B": File{false, true, false},
}
Chessboard把列的标识符映射到File值。
每个File都是一个布尔值切片,表示一条竖列中的各个格子。
没有这些类型定义,board就会是map[string][]bool,这会让人更难理解我们到底在表示什么。
作为一名国际象棋爱好者,你想写出自己的版本。 没错,网上可能已经有很多国际象棋的实现,但你的将是独一无二的!
棋盘上的每个方格都由字母和数字的组合来标识:
A B C D E F G H
8 # _ _ _ # _ _ # 8
7 _ _ _ _ _ _ _ _ 7
6 _ _ _ _ # _ _ # 6
5 _ # _ _ _ _ _ # 5
4 _ _ _ _ _ _ # # 4
3 # _ # _ _ _ _ # 3
2 _ _ _ _ _ _ _ # 2
1 # _ _ _ _ _ _ # 1
A B C D E F G H
实现 CountInFile(board Chessboard, file string) int 函数。
它应该通过遍历一个映射来统计被占据的方格总数。
返回一个整数。
如果给定的列在映射中找不到,则返回计数零(0)。
CountInFile(board, "A")
// => 3
实现 CountInRank(board Chessboard, rank int) int 函数。
它应该通过遍历给定的行来统计被占据的方格总数。
返回一个整数。
如果给定的行不是有效的(不在 1 到 8 之间,包含两端),则返回计数零(0)。
CountInRank(board, 2)
// => 1
实现 CountAll(board Chessboard) int 函数。
它应该统计棋盘中有多少个存在的方格,并返回一个整数。
由于你不需要检查方格的内容,可以考虑使用 range,同时省略 index 和 value。
CountAll(board)
// => 64
实现 CountOccupied(board Chessboard) int 函数。
它应该统计棋盘中有多少个方格被占据。
返回一个整数。
CountOccupied(board)
// => 15