模块 4 · 第 1 课(共 5)课程中的16/50~8 min
模块课程(1/5)
定长数组
在 Go 中,数组具有固定长度,并融入其类型:[N]T。
它是一个很少直接在应用程序代码中使用的原语 - 您将
几乎总是使用切片(下一课),它是动态的
数组的视图。
尽管如此,充分理解数组仍然至关重要:Go 中的一切都是构建的 在他们之上。
声明和初始化
Go
var a [3]int = [3]int{10, 20, 30}
b := [3]int{1, 2, 3} // inference with :=
c := [3]int{} // all zero: [0, 0, 0]
d := [...]int{1, 2, 3, 4} // length inferred = 4数组的零值是声明长度的数组,其中每个 元素为零值:
Go
var nums [5]int // [0 0 0 0 0]索引和 len
Go
a := [3]int{10, 20, 30}
fmt.Println(a[0]) // 10
a[1] = 99
fmt.Println(len(a)) // 3超出范围的访问会导致运行时恐慌(不是静默的未定义 就像C)中那样。
长度是类型的一部分
Go
var a [3]int
var b [4]int
// a = b // ERROR: different types[3]int 和 [4]int 是 不同的类型,即使两者都持有
int。这就是为什么数组很少传递给函数的原因:你必须
将长度硬编码到参数类型中。
按值复制
与切片(参考)和映射(参考)不同,数组是复制的 值:
Go
a := [3]int{1, 2, 3}
b := a // copy
b[0] = 99
fmt.Println(a[0]) // 1 — a is unchanged这同样适用于传递给函数时:函数接收它的 自己的副本。
什么时候使用数组?
- 编译时已知的固定大小缓冲区(例如 MD5 的
[16]byte)。 - 复合映射键(切片不是“可比较的”,数组是)。
- 极致性能(无间接,缓存友好)。
对于 99% 的代码:使用切片。
尝试一下
锻炼#go.m4.l1.e1
尝试:0加载中...
将 a 声明为由 3 个整数组成的数组,其值为 10、20、30 并打印其长度。
正在加载编辑器...
显示提示
数组字面量:`[3]int{a, b, c}`。
3 次尝试后可用的解决方案
锻炼#go.m4.l1.e2
尝试:0加载中...
将 b 声明为 5 个整数(全部为零)的数组,并将 99 分配给位置 2。
正在加载编辑器...
显示提示
`var b [5]int` 开头为 [0 0 0 0 0]。
3 次尝试后可用的解决方案
Quiz#go.m4.l1.e3
准备好[3]int 和 [4]int 是同一类型吗?
Go
var a [3]int
var b [4]int
// a = b ?回顾
[N]T:固定长度,类型的一部分。- 零值:每个元素都为零值。
[...]int{...}让编译器推断长度。- 按值复制(包括内部函数)。
- 超出范围 = 恐慌,而不是未定义。
- 在实践中,使用切片,它是数组的视图。