Skip to content

Latest commit

 

History

History
100 lines (80 loc) · 3.66 KB

File metadata and controls

100 lines (80 loc) · 3.66 KB

多维数组

数组可以有多个维度。然而,在没有严肃理由的情况下,使用超过三个维度会使你的程序难于阅读,并可能产生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)