数组 是一个由 固定长度 的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。因为数组的长度是固定的,因此在 Go 语言中很少直接使用数组。和数组对应的类型是 slice(切片) ,它是可以增长和收缩的动态序列, slice
功能也更灵活,下一期我们再讨论 slice
。
声明数组
可以使用 [n]Type
来声明一个数组。其中 n
表示数组中元素的数量, Type
表示每个元素的类型。
var arr [5]int
上面的语句声明了一个长度为 5
的整型数组,因为声明时没有指定数组元素的值,所以数组中的每个元素都会被自动初始化对应类型的零值,对应整型数组来说,零值为 0
,因此数组 arr
中所有元素的值都为 0
。我们可以通过索引对数组中的元素赋值。
var arr [5]int
arr[0] = 15
arr[1] = 20
arr[2] = 25
arr[3] = 30
arr[4] = 35
fmt.Println(arr)
运行该程序会输出 [15 20 25 30 35]
。当然,也可以直接在声明时对数组进行初始化。
var arr = [5]int{15, 20, 25, 30, 35}
或者直接用短声明:
arr := [5]int{15, 20, 25, 30, 35}
当然,如果你只想给数组前面的某几个元素赋值也是可以的,其他没被赋值的元素会被自动赋值为类型对应的零值。例如:
arr := [5]int{15, 20} // [15 20 0 0 0]
有时要初始化数组的元素个数太多,我们可以不计算数组元素的个数,直接使用 ...
让编译器为我们计算该数组的长度。
arr := [...]int{15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70}
我们也可以通过指定索引,方便地对数组某几个元素赋值:
arr := [5]int{1:100, 4:200}
fmt.Println(arr) // [0 100 0 0 200]
特别注意数组的长度是类型的一部分,所以 [3]int
和 [5]int
是不同的类型。
package main
import "fmt"
func main() {
arr1 := [3]int{15, 20, 25}
arr2 := [5]int{15, 20, 25, 30, 35}
fmt.Printf("type of arr1 is %T\n", arr1)
fmt.Printf("type of arr2 is %T\n", arr2)
}
运行该程序输出如下:
type of arr1 is [3]int
type of arr2 is [5]int
获取数组的长度
使用内置的 len
函数将返回数组中元素的个数,即数组的长度。
arr := [...]int{15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70}
fmt.Println(len(arr)) // 12
数组是值类型
Go 中的数组是值类型而不是引用类型。当数组赋值给一个新的变量时,该变量会得到一个原始数组的一个副本。如果对新变量进行更改,不会影响原始数组。
arr := [3]int{15, 20, 25}
copy := arr
copy[0] = 10
fmt.Println(arr) // [15 20 25]
fmt.Println(copy) // [10 20 25]
同理,当数组作为参数传递给函数时,它们是按值传递,原始数组保持不变。
package main
import "fmt"
func change(array [3]int) {
array[0] = 0
fmt.Println("array in func = ", array)
}
func main() {
arr := [3]int{15, 20, 25}
change(arr)
fmt.Println("arr in main = ", arr)
}
运行该程序会输出:
array in func = [0 20 25]
arr in main = [15 20 25]
获取数组元素
使用 for range
循环可以获取数组每个索引以及索引上对应的元素。
package main
import "fmt"
func main() {
arr := [3]int{15, 20, 25}
for index, value := range arr {
fmt.Printf("arr[%d] = %d\n", index, value)
}
}
运行该程序输出如下:
arr[0] = 15
arr[1] = 20
arr[2] = 25
当然,如果你只想获得元素的值而忽略索引值,可以采用我们之前讲过的空白标识符来代替索引:
for _, value := range arr {...}
多维数组
和你见过的其他语言一样,在 Go 中也可以定义多维数组。
arr := [3][2]string{
{"15", "20"},
{"25", "22"},
{"25", "22"}}
fmt.Println(arr) // [[15 20] [25 22] [25 22]]
参考文献:
[1] Alan A. A. Donovan; Brian W. Kernighan, Go 程序设计语言, Translated by 李道兵, 高博, 庞向才, 金鑫鑫 and 林齐斌, 机械工业出版社, 2017.