数组可以有多个维度。然而,在没有严肃理由的情况下,使用超过三个维度会使你的程序难于阅读,并可能产生bug。
Tip: 数组可以存储所有类型的元素,这里我们只用整数讲解,因为他们更容易理解和类型。
下面的Go代码演示了如何创建一个二维数组(twoD)和另一个三维数组(threeD):
twoD := [4][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12},{13, 14, 15, 16}}
threeD := [2][2][2]int{{{1, 0}, {-2, 4}}, {{5, -1}, {7, 0}}}
访问、分配或打印这两个数组中的一个元素是很容易的。例如,twoD数组的第一个元素是twoD[0][0]
,它的值是1。
因此,使用多层循环遍历threeD 的每一个元素可以通过下面的代码实现:
for i := 0; i < len(threeD); i++ {
for j := 0; j < len(v); j++ {
for k := 0; k < len(m); k++ {
}
}
}
我们看到,我们需要和数组维度一样的循环的数量来遍历所有元素。这个规则对切片slice
也适用,下章将会讲到。这里使用x, y, z
替代i, j, k
会比较好。
usingArrays.go
展示了如何在Go中使用数组,下面分成三部分进行讲解。
第一部分的代码如下:
package main
import (
"fmt"
)
func main() {
anArray := [4]int{1, 2, 4, -4}
twoD := [4][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14,15, 16}}
threeD := [2][2][2]int{{{1, 0}, {-2, 4}}, {{5,-1},{7, 0}}}
这里我们定义了三个数组变量分别叫 anArray, twoD 和 threeD。
第二部分的代码如下:
fmt.Println("The length of", anArray, "is", len(anArray))
fmt.Println("The first element of", twoD, "is", twoD[0][0])
fmt.Println("The length of", threeD, "is", len(threeD))
for i := 0; i < len(threeD); i++ {
v := threeD[i]
for j := 0; j < len(v); j++ {
m := v[j]
for k := 0; k < len(m); k++ {
fmt.Print(m[k], " ")
}
}
fmt.Println()
}
我们从第一个for循环中得到一个二维数组(threeD[i]
), 同理,第二个for循环中得到一个一维数组。最后一个for循环遍历得到的一维数组得到里面的每一个元素。
最后一部分代码:
The last code part comes with the next Go code:
for _, v := range threeD {
for _, m := range v {
for _, s := range m {
fmt.Print(s, " ")
}
}
fmt.Println()
}
}
range
关键字的作用与上一个代码段的for循环中使用的迭代变量完全相同,但它的作用更优雅、更清晰。然而,如果想要提前知道将要执行的迭代次数,那么就不能使用range
关键字。
range
关键字也适用于Go映射,这使得它非常方便,也是我喜欢的迭代方式。正如将在第9章中看到的Go - Goroutines、channel和pipeline中的并发性,range关键字也适用于channel。
执行 usingArrays.go
结果输出如下:
$ go run usingArrays.go
The length of [1 2 4 -4] is 4
The first element of [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16]] is 1
The length of [[[1 0] [-2 4]] [[5 -1] [7 0]]] is 2
1 0 -2 4
5 -1 7 0
1 0 -2 4
5 -1 7 0
数组最大的问题之一是越界错误,这意味着试图访问数组中不存在的元素。这就像试图访问一个只有5个元素的数组的第6个元素。Go编译器将此认作编译检测的编译问题,因为这有助于开发工作流。因此,Go编译器能检测数组越界错误并给出如下错误提示:
./a.go:10: invalid array index -1 (index must be non-negative)
./a.go:10: invalid array index 20 (out of bounds for 2-element array)