介绍
在现代软件开发中,我们经常需要存储大量数据。
根据我们所学的内容,我们可以轻松定义许多变量。
然而,如果我们需要使用变量来记录一家公司员工的姓名,数据规模达到数百或数千,我们是否必须逐个定义它们呢?
当然不是。对于具有相似属性的数据,我们可以使用数组来定义和存储它们。
我们可以将数组视为一组变量的集合,它们像火车一样聚集在一起。当我们想要找到特定的变量时,只需要知道列车号(数组名)和座位号(索引)。然后我们就可以找到并操作该变量,而无需知道它的名称。
在本节中,我们将学习数组的各种基本操作。
知识点:
- 数组定义
- 数组初始化
- 数组遍历
- 数组元素的特性
数组定义
我们如何定义一个数组?
让我们回顾一下学习变量时的情况。我们是如何定义一个 int 变量的?
var a int
即:
var 变量名 变量类型
类似地,我们可以这样定义一个 int 数组:
var a [10]int
即:
var 变量名 [元素数量]变量类型
通过这种方式,我们定义了一个名为 a 的基本 int 数组,其容量为 10。
初始化列表
在了解了如何定义数组之后,让我们学习如何初始化数组。
在初始化数组时,我们可以使用初始化列表来设置数组元素的初始值。
在 ~/project 目录下创建一个 array.go 文件:
cd ~/project
touch array.go
在 array.go 中编写以下代码:
package main
import "fmt"
func main() {
// 自动初始化为元素类型的零值
var simpleArray [3]int
// 使用指定的初始值初始化,并使用零值填充缺失的元素
var numArray = [3]int{1, 2}
// 使用指定的初始值初始化
var cityArray = [2]string{"London", "Chengdu"}
fmt.Println(simpleArray) // [0 0 0]
fmt.Println(numArray) // [1 2 0]
fmt.Println(cityArray) // [London Chengdu]
}
运行代码:
go run ~/project/array.go
预期输出:
[0 0 0]
[1 2 0]
[London Chengdu]
上述代码展示了使用初始化列表指定初始值的三种方式:
- 不传递列表:初始化为元素类型的零值
- 传递部分列表:使用指定值初始化指定元素,并将剩余元素初始化为零值
- 传递完整列表:使用指定值初始化
请注意,如果传递的列表长度大于数组的元素数量,代码将无法编译。
推断长度初始化
在使用初始化列表初始化数组时,你必须确保提供的初始值数量小于或等于数组的元素数量。
通常情况下,你可以依赖编译器根据初始值推断数组的长度。
修改 array.go 文件如下:
package main
import "fmt"
func main() {
var simpleArray [3]int
var numArray = [...]int{1, 2}
var cityArray = [...]string{"London", "Chengdu"}
fmt.Println(simpleArray) // [0 0 0]
fmt.Println(numArray) // [1 2]
fmt.Printf("The type of numArray is: %T\n", numArray) // The type of numArray is: [2]int
fmt.Println(cityArray) // [London Chengdu]
fmt.Printf("The type of cityArray is: %T\n", cityArray) // The type of cityArray is: [2]string
}
运行代码:
go run ~/project/array.go
预期输出:
[0 0 0]
[1 2]
The type of numArray is: [2]int
[London Chengdu]
The type of cityArray is: [2]string
指定索引初始化
有时,我们可能希望为数组中某些特定位置分配初始值,而不管是否使用初始化列表或推断长度。
修改 array.go 文件如下:
package main
import "fmt"
func main() {
a := [...]int{1: 1, 3: 5}
fmt.Println(a) // [0 1 0 5]
fmt.Printf("The type of array a is: %T\n", a) // The type of array a is: [4]int
}
运行代码:
go run ~/project/array.go
预期输出:
[0 1 0 5]
The type of array a is: [4]int
上述代码指定了索引为 1 和 3 的元素的初始值分别为 1 和 5。它还使用了推断长度的初始化方法,这是你需要学习的。
注意:在计算中,索引从 0 开始。
数组遍历
有时,我们需要访问数组中的每个元素并逐个对它们进行操作。
这里,我们介绍两种遍历数组的方法:
在 array.go 中编写以下代码:
package main
import "fmt"
func main() {
a := [...]int{123, 321, 456, 777}
// 方法 1: range
fmt.Println("使用 range 遍历数组")
for index, value := range a {
fmt.Println(index, " ", value)
}
// 方法 2: 使用索引
fmt.Println("\n使用索引遍历数组")
for i := 0; i < len(a); i++ {
fmt.Println(a[i])
}
}
运行代码:
go run ~/project/array.go
预期输出:
使用 range 遍历数组
0 123
1 321
2 456
3 777
使用索引遍历数组
123
321
456
777
上述两种方法都可以用于遍历整个数组。
访问数组元素
要访问数组中的特定元素(本质上是一个变量),我们使用索引。
与大多数编程语言类似,数组的索引从 0 开始,最后一个元素的索引是 len-1。
如果在代码中使用了超过此限制的索引,将会导致越界错误。
要访问数组 a 的第 i 个元素,可以使用以下表示法:
a[i]
即:
数组名[元素索引]
数组的值类型特性
数组是值类型;赋值数组或将数组作为参数传递时,会复制整个数组。换句话说,你修改的是副本的值,而不是原始数组。
在 array.go 中编写以下代码:
package main
import "fmt"
func modifyArray(x [3]int) {
x[0] = 100
}
func main() {
a := [3]int{10, 20, 30}
modifyArray(a) // `modifyArray` 中的变量 `x` 是 `a` 的副本
fmt.Println(a) // [10 20 30]
}
运行代码:
go run ~/project/array.go
输出结果为:
[10 20 30]
从上述代码可以看出,当数组 a 传递给 modifyArray 函数时,实际上传递的是其原始数组的副本。
在函数中修改数组 x 的值不会影响原始数组 a。
总结
在本实验中,我们学习了:
- 如何定义数组
- 数组初始化的三种方法
- 数组的特性以及如何访问其元素
数组在实际开发中并不常用,但它们是学习 Go 中常用数据结构的基础。
希望所有的 Gophers 能够勤加练习,并学会将所学知识应用到实际中。



