Skip to content

Go 数组

Go 中的 数组 (array) 是具有固定长度 (fixed length) 的、单一特定类型的元素的有序序列。可以把它看作是一个固定大小的容器,其中每个槽位都存放相同类型的值。

Go 数组的主要特点:

数组将其元素存储在一块连续内存 (contiguous block of memory) 中。

通过指定其大小和元素类型来声明数组:

var variableName [SIZE]elementType

其中,SIZE 必须是一个非负整数常量,而 elementType 是任何有效的 Go 类型。

示例:声明一个名为 scores 的数组,用于存储 5 个整数值。

var scores [5]int // 声明一个包含 5 个整数的数组,初始化为 [0 0 0 0 0]

可以在声明时使用数组字面量 (array literal) 来初始化数组:

  1. 指定大小并提供值:
var grades = [3]int{85, 92, 78} // 包含 3 个 int 的数组
// 使用短声明语法
names := [4]string{"Alice", "Bob", "Charlie"} // 大小为 4,最后一个元素为 ""(零值)

字面量 {...} 中的值数量不能超过指定的大小。

  1. 让 Go 推断大小:

使用 ... 代替具体大小,编译器将根据字面量中的元素数量来确定数组的长度。

temperatures := [...]float64{19.5, 22.0, 21.7} // 包含 3 个 float64 的数组,大小由编译器推断
  1. 在特定索引处指定值:
counters := [5]int{1: 10, 3: 30} // 包含 5 个 int 的数组:[0 10 0 30 0]
// 索引 0, 2, 4 获取零值 (0)

访问和修改数组元素 (Accessing and Modifying Array Elements)

Section titled “访问和修改数组元素 (Accessing and Modifying Array Elements)”

使用数组名后跟方括号 [] 中的索引来访问元素。请记住,索引从 0 开始。

var data [3]int
data[0] = 100 // 将 100 赋值给第一个元素
data[1] = 200
data[2] = 300
firstValue := data[0] // 读取第一个元素的值 (firstValue 为 100)
// data[3] = 400 // 编译时错误:索引 3 对于大小为 3 的数组越界

让我们操作一个数字数组:

package main
import "fmt"
func main() {
// 声明并初始化一个包含 5 个整数的数组
numbers := [5]int{10, 20, 30, 40, 50}
fmt.Println("Original array:", numbers)
// 修改索引为 2 的元素
numbers[2] = 35
fmt.Println("Modified array:", numbers)
// 使用循环访问并打印单个元素
fmt.Println("\nAccessing elements individually:")
for i := 0; i < len(numbers); i++ {
fmt.Printf("Element[%d] = %d\n", i, numbers[i])
}
// 使用 range 关键字迭代(Go 的惯用法)
fmt.Println("\nIterating with range:")
sum := 0
for index, value := range numbers {
fmt.Printf("Index: %d, Value: %d\n", index, value)
sum += value
}
fmt.Printf("\nSum of elements: %d\n", sum)
// 使用 len() 获取数组的长度
fmt.Printf("Length of array: %d\n", len(numbers))
}

输出:

Original array: [10 20 30 40 50]
Modified array: [10 20 35 40 50]
Accessing elements individually:
Element[0] = 10
Element[1] = 20
Element[2] = 35
Element[3] = 40
Element[4] = 50
Iterating with range:
Index: 0, Value: 10
Index: 1, Value: 20
Index: 2, Value: 35
Index: 3, Value: 40
Index: 4, Value: 50
Sum of elements: 155
Length of array: 5

数组有其用途,尤其是在编译时已知精确的元素数量且固定不变的情况下。然而,在惯用的 Go 代码中,切片 (slices) 因其灵活性(动态大小)而被更频繁地使用。

需要记住的主要区别:

特性 (Feature)数组 ([N]T)切片 ([]T)
大小 (Size)固定,是类型的一部分动态,可以增长/收缩
传递给函数 (Passing to Functions)值传递(复制整个数组)值传递(复制切片头,指向相同的底层数组)
声明 (Declaration)var a [5]int, a := [...]int{1,2}var s []int, s := []int{1,2}, make([]int, 5)
常见用法 (Common Usage)较少见,用于固定大小集合非常常见,灵活的数据序列

虽然不如一维数组常见,Go 也支持:

多维数组 (Multi-dimensional Arrays): 数组的数组,创建网格状结构。

var matrix [2][3]int // 一个 2x3 的整数网格
matrix[0][1] = 5

将数组传递给函数 (Passing Arrays to Functions): 如前所述,数组是按值传递的。如果函数需要修改原始数组,必须传递数组的指针。

func modifyArray(arr *[3]int) {
(*arr)[0] = 100 // 通过指针修改原始数组
// arr[0] = 100 // 快捷语法也有效
}
func main() {
myArray := [3]int{1, 2, 3}
modifyArray(&myArray) // 传递数组的地址 (指针)
fmt.Println(myArray) // 输出: [100 2 3]
}

由于复制的开销和固定大小的限制,除非特别需要固定大小的属性,否则通常优先传递切片而不是数组(或数组的指针)。