Go 语言类型 数组
基本概念
数组(Array)是一组同类型元素的集合。
Go 语言中数组包含以下部分:
- 长度:数组包含元素的数量,是数组类型的一部分。不同长度的数组是不同类型,它们之间不能互相转换。
- 类型:数组内元素的数据类型。所有元素必须为同一类型。
- 元素:组成数组的数据。每个数组元素都有一个编号,称为数组下标或索引。
数组属于值类型,一旦声明,类型和长度都不可修改。数组是切片和映射的基础数据结构。
声明和初始化
声明和初始化数组常用有 4 种方式,见下面示例:
package main
import "fmt"
func main() {
// 只声明数组,元素值为数据类型的零值,之后允许赋值修改
var a [3]int
// 声明并部分初始化数组,用于全局定义
var b = [3]int{1, 2}
// 简短声明格式,同时完全初始化数组
c := [3]int{1, 2, 3}
// 使用 new 函数创建并初始化数组,返回指向该数组的指针
d := new([3]int)
// 输出:[0 0 0] [1 2 0] [1 2 3] &[0 0 0]
fmt.Println(a, b, c, d)
}
初始化数组时,可使用 ...
替代长度值,由编译器根据元素数量自动推断长度。而在定义元素时,可用数组下标来定义值,没有定义的数组下标值为类型零值:
package main
import "fmt"
func main() {
// 省略数组长度,由编译器推断
a := [...]int{1, 2, 3}
// 使用索引初始化数组元素。索引不能越界,定义顺序没要求
b := [5]int{3: 30, 1: 10}
// 混合模式,数组长度由元素最高索引决定
// d 的索引跟在 2: "c" 后面所以为 3
// e 的索引依此类推
c := [...]string{"a", 5: "f", 2: "c", "d", "e"}
// 输出:[1 2 3] [0 10 0 30 0] [a c d e f]
fmt.Println(a, b, c)
}
数组操作
由于数组长度不可变,因此很少使用,切片可以完全替代数组使用。
修改元素值
数组索引从 0
开始,可以直接通过索引修改元素值。索引必须位于边界范围之内,且只能为正整数,不支持从末尾开始索引:
package main
import "fmt"
func main() {
// 创建包含两个整数的数组
numbers := [2]int{1, 2}
fmt.Println("初始第一个元素的值:", numbers[0])
// 修改数组第一个元素值
numbers[0] = 10
fmt.Println("修改后第一个元素的值:", numbers[0])
// 尝试访问或修改超出数组边界的元素将导致编译时错误
//numbers[2] = 11 // 报错:invalid array index 2 (out of bounds for 2-element array)
// 不支持倒序索引
//numbers[-1] = 11 // 报错:invalid array index -1 (index must be non-negative)
}
遍历数组
使用 for
循环来遍历数组,可以配合 range
语句直接获取元素值:
package main
import (
"fmt"
)
func main() {
numbers := [2]int{1, 2}
// 使用传统 for 循环通过索引遍历数组
fmt.Println("使用传统 for 循环遍历数组:")
for i := 0; i < len(numbers); i++ {
fmt.Printf("索引:%d, 值:%d\n", i, numbers[i])
}
// 使用 range 关键字遍历数组,同时获取索引和元素值
fmt.Println("使用 range 遍历数组:")
for i, v := range numbers {
fmt.Printf("索引:%d, 值:%d\n", i, v)
}
}
传递数组
数组作为函数参数时是通过值传递:
package main
import "fmt"
func main() {
// 调用函数,传递数组参数
resultArray := doubleArrayValues([...]int{1, 2, 3, 4, 5})
fmt.Println("函数返回:", resultArray)
}
// doubleArrayValues 函数接收一个整型数组,并返回一个新数组,其中每个元素值是原值两倍
func doubleArrayValues(inputArray [5]int) [5]int {
var result [5]int
for i, value := range inputArray {
result[i] = value * 2
}
return result
}
包括将数组赋值给其他变量,也是传递数据副本:
package main
import "fmt"
func main() {
// 初始化两个整型数组
a := [2]int{1, 2}
b := [2]int{3, 4}
// 将两个数组嵌套为一个新二维数组
nestedArray := [2][2]int{a, b}
// 修改 b 第一个元素值
b[0] = 100
// 展示二维数组值,确认修改 b 不会影响 nestedArray
fmt.Printf("a: %v, b(modified): %v, nestedArray: %v\n", a, b, nestedArray)
}
当要传递数组很大时,可以考虑传递数组指针或数组切片。
多维数组
数组本身只有一个维度,但可以组合多个数组创建多维数组。数组维度是指数组下标个数,多维数组有多个下标。多维数组中每个元素也是数组,用于表达具有依赖关系的数据(例如坐标)。下面是一个三维数组示例:
package main
import "fmt"
func main() {
// 构造一个 2x2x2 三维数组
threeDArray := [2][2][2]int{
{
{1, 2},
{3, 4},
},
{
{5, 6},
{7, 8},
},
}
// 访问和修改
fmt.Printf("位于(1, 0, 1)的元素值为:%d\n", threeDArray[1][0][1])
threeDArray[1][0][1] = 99
fmt.Printf("修改后,整个三维整型数组值为:%v\n", threeDArray)
}
虽然数组 threeDArray
可以存放 2x2x2=8
个整型元素,但数组长度为 2。