Go 语言中的数组操作

GolangGolangBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在现代软件开发中,我们经常需要存储大量数据。

根据我们所学的内容,我们可以轻松定义许多变量。

然而,如果我们需要使用变量来记录一家公司员工的姓名,数据规模达到数百或数千,我们是否必须逐个定义它们呢?

当然不是。对于具有相似属性的数据,我们可以使用数组来定义和存储它们。

我们可以将数组视为一组变量的集合,它们像火车一样聚集在一起。当我们想要找到特定的变量时,只需要知道列车号(数组名)和座位号(索引)。然后我们就可以找到并操作该变量,而无需知道它的名称。

在本节中,我们将学习数组的各种基本操作。

知识点:

  • 数组定义
  • 数组初始化
  • 数组遍历
  • 数组元素的特性

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("Golang")) -.-> go/BasicsGroup(["Basics"]) go(("Golang")) -.-> go/DataTypesandStructuresGroup(["Data Types and Structures"]) go(("Golang")) -.-> go/FunctionsandControlFlowGroup(["Functions and Control Flow"]) go/BasicsGroup -.-> go/values("Values") go/BasicsGroup -.-> go/variables("Variables") go/DataTypesandStructuresGroup -.-> go/arrays("Arrays") go/DataTypesandStructuresGroup -.-> go/slices("Slices") go/DataTypesandStructuresGroup -.-> go/structs("Structs") go/FunctionsandControlFlowGroup -.-> go/for("For") go/FunctionsandControlFlowGroup -.-> go/range("Range") subgraph Lab Skills go/values -.-> lab-149075{{"Go 语言中的数组操作"}} go/variables -.-> lab-149075{{"Go 语言中的数组操作"}} go/arrays -.-> lab-149075{{"Go 语言中的数组操作"}} go/slices -.-> lab-149075{{"Go 语言中的数组操作"}} go/structs -.-> lab-149075{{"Go 语言中的数组操作"}} go/for -.-> lab-149075{{"Go 语言中的数组操作"}} go/range -.-> lab-149075{{"Go 语言中的数组操作"}} end

数组定义

我们如何定义一个数组?

让我们回顾一下学习变量时的情况。我们是如何定义一个 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 能够勤加练习,并学会将所学知识应用到实际中。