引入
Go 里要按顺序保存多个相同类型的数据,最基础的方式就是数组。数组长度在声明时就固定了,不能增删,适合数据量确定的场景。虽然实际开发中 Go 切片 用得更多,但数组是理解切片的基础。
正文
定义
定义
数组是用来按顺序保存多个相同类型的数据,长度固定。声明时必须指定长度和元素类型,长度是数组类型的一部分,
[3]int和[5]int是不同类型。
语法
// 声明(零值初始化)
var arr [5]int
// 声明并初始化
arr := [3]int{1, 2, 3}
// 编译器推断长度
arr := [...]int{10, 20, 30}例子
声明和初始化
var a [3]int
fmt.Println(a) // [0 0 0]
b := [3]int{1, 2, 3}
fmt.Println(b) // [1 2 3]
c := [...]int{10, 20, 30, 40}
fmt.Println(len(c)) // 4[…] 让编译器自动算长度,写起来更方便。
通过索引访问和修改
arr := [3]string{"Go", "Rust", "Python"}
fmt.Println(arr[0]) // Go
fmt.Println(arr[2]) // Python
arr[1] = "Java"
fmt.Println(arr) // [Go Java Python]索引从 0 开始,超出范围会编译报错或运行时 panic。
部分初始化
arr := [5]int{0: 10, 3: 40}
fmt.Println(arr) // [10 0 0 40 0]指定索引赋值,其余元素为零值。
遍历数组
arr := [3]int{10, 20, 30}
// for 循环
for i := 0; i < len(arr); i++ {
fmt.Println(i, arr[i])
}
// for range
for i, v := range arr {
fmt.Println(i, v)
}for range 更简洁,i 是索引,v 是值的副本。
数组是值类型
a := [3]int{1, 2, 3}
b := a
b[0] = 100
fmt.Println(a) // [1 2 3](没变)
fmt.Println(b) // [100 2 3]数组赋值或传参都会复制整个数组,修改副本不影响原始值。
数组比较
a := [3]int{1, 2, 3}
b := [3]int{1, 2, 3}
c := [3]int{1, 2, 4}
fmt.Println(a == b) // true
fmt.Println(a == c) // false同类型数组可以用 == 比较,逐元素对比。
多维数组
matrix := [2][3]int{
{1, 2, 3},
{4, 5, 6},
}
fmt.Println(matrix[0][1]) // 2多维数组就是数组的元素也是数组。
常见写法
| 写法 | 说明 |
|---|---|
var arr [5]int | 声明,元素为零值 |
arr := [3]int{1, 2, 3} | 声明并初始化 |
arr := […]int{1, 2, 3} | 编译器推断长度 |
arr[i] | 通过索引访问 |
arr[i] = v | 通过索引修改 |
len(arr) | 获取数组长度 |
for i, v := range arr | 遍历数组 |
特点
- 数组长度固定,声明后不能改变
- 长度是类型的一部分,
[3]int和[5]int是不同类型 - 数组是值类型,赋值和传参会复制整个数组
- 同类型数组可以用
==比较 - 索引越界会编译报错(常量索引)或 panic(变量索引)
- 实际开发中 Go 切片 用得更多,数组主要用于底层实现
理解
数组就是一个固定大小的盒子,里面按顺序放同一类型的数据。通过索引能快速找到每个元素,但长度不能变,传参还会整个复制,用起来不太灵活。所以在 Go 里,数组更多是切片的基础,日常写代码几乎都用切片代替。
引出
数组长度固定不够灵活,接下来看 Go 切片,学习动态长度的序列,也是 Go 里最常用的集合类型。