Go 语言数组

定长数组、值语义、多维数组,以及为什么日常都用切片。

Beginner
Key PointsGo 的数组长度是类型的一部分:`[3]int` 和 `[4]int` 是不同类型。

声明与初始化

Go
var a [3]int                      // [0 0 0]
b := [3]int{1, 2, 3}
c := [...]int{1, 2, 3, 4}         // 长度由编译器数
d := [5]int{1: 10, 4: 50}         // 按下标初始化

fmt.Println(a)
fmt.Println(b, len(b))
fmt.Println(c, len(c))
fmt.Println(d)
Output
[0 0 0]
[1 2 3] 3
[1 2 3 4] 4
[0 10 0 0 50]

值语义

Go
func modify(arr [3]int) {
	arr[0] = 999           // 改的是副本
}

x := [3]int{1, 2, 3}
modify(x)
fmt.Println(x)             // 原数组不变

// 想改原数组必须传指针
func modifyPtr(arr *[3]int) {
	arr[0] = 999
}
modifyPtr(&x)
fmt.Println(x)
Output
[1 2 3]
[999 2 3]

Array assignment and passing copy the whole thing. Copying three ints is free; copying a hundred thousand elements per call is not. That is why Go uses slices day to day.

遍历

Go
arr := [4]string{"a", "b", "c", "d"}

for i := 0; i < len(arr); i++ {
	fmt.Print(arr[i], " ")
}
fmt.Println()

for i, v := range arr {
	fmt.Print(i, v, " ")
}
fmt.Println()
Output
a b c d 
0a 1b 2c 3d 

多维数组

Go
var grid [2][3]int

for i := 0; i < 2; i++ {
	for j := 0; j < 3; j++ {
		grid[i][j] = i*3 + j
	}
}
fmt.Println(grid)

// 字面量
m := [2][3]int{
	{1, 2, 3},
	{4, 5, 6},
}
fmt.Println(m[1][2])
Output
[[0 1 2] [3 4 5]]
6

数组 vs 切片

AspectArray [3]intSlice []int
长度类型的一部分,固定运行时可变
赋值整体复制共享底层数组
传参复制复制头部(3 个字段)
能否 append不能能
常用度少绝大多数场景
Arrays beat slices in one case: fixed small length, e.g. sha256.Sum256 returning [32]byte. Arrays can be map keys; slices cannot.

Friends & Partners