Go语言数组全面解析:定义、初始化与实战应用

追风的人
追风的人
发布时间:2026-10-16 | 2人浏览过
原创

本文详细介绍Go语言中数组的定义、初始化、遍历及应用实例。包括固定长度声明、省略长度的自动推断、按索引初始化等方法,以及通过for和range遍历的技巧。文章还包含冒泡排序、数值处理等实战代码,并解析二维数组结构与函数传参规则,助您快速掌握Go数组核心操作。

一、数组的基本概念与定义

数组是Go语言中最基础的数据结构之一,用于存储同一数据类型的连续内存块。其核心特性在于长度在定义后不可修改,且数组类型由“长度”和“元素类型”共同决定。例如,[3]int与[4]int是不同的类型,即便元素类型相同。

第1步:声明数组语法

使用 var 关键字进行标准声明,需明确指定长度和类型:

var variable_name [SIZE] variable_type

参数说明:

  • variable_name:变量名。
  • SIZE:数组长度,必须是常量或常量表达式。
  • variable_type:存储元素的类型(如 int, string, float64 等)。

第2步:数组示例与零值机制

在Go中,未显式初始化的数组元素会自动填充为对应类型的“零值”(int为0,string为空字符串"",bool为false)。

package main

import "fmt"

func main() {
	var a [3]int      // 长度3的int数组
	var b [2]string   // 长度2的string数组

	// 输出类型与内容
	fmt.Printf("a: %T\n", a)       // 输出: [3]int
	fmt.Printf("b: %T\n", b)       // 输出: [2]string
	fmt.Printf("a content: %v\n", a) // 输出: [0 0 0]
	fmt.Printf("b content: %v\n", b) // 输出: [ ]
}

二、数组的初始化策略

除了依赖零值,开发者可通过多种方式在声明时赋予初值。正确的初始化不仅能简化代码,还能避免逻辑错误。

第3步:使用初始化列表赋值

通过花括号 {} 直接指定元素值。若提供的值少于数组长度,剩余部分仍补零;若多于长度则编译报错。

package main

import "fmt"

func main() {
	var a = [3]int{1, 2, 3}          // 完全填满
	var b = [2]string{"hello"}       // 第二个元素为空串
	var c = [2]bool{true, false}

	// 类型推断简写
	a1 := [2]int{1, 2}

	fmt.Printf("a: %v\n", a)
	fmt.Printf("b: %v\n", b)
	fmt.Printf("c: %v\n", c)
	fmt.Printf("a1: %v\n", a1)
}

第4步:省略长度与指定索引初始化

1. 省略长度 ...:
当无法确定或不想手动计算长度时,可使用 ... 代替具体数字,编译器会根据元素个数自动推导长度。

var a = [...]int{1, 2, 3, 4, 5} // 长度自动推导为5
var b = [...]string{"hello", "world"} // 长度为2

2. 指定索引赋值:
可仅对特定位置赋值,未指定的位置默认为零值。这在稀疏数组处理中非常有用。

package main

import "fmt"

func main() {
	var a = [...]int{0: 1, 2: 2}       // a为 [1 0 2]
	var b = [...]string{1: "hello"}     // b为 [ hello]
	var c = [...]bool{2: true, 5: false} // c为 [false false true false false false]

	fmt.Printf("a: %v\n", a)
	fmt.Printf("b: %v\n", b)
	fmt.Printf("c: %v\n", c)
}

三、数组的访问与遍历

数组通过下标(索引)访问,索引从0开始,最大有效值为 长度-1。超出范围将触发panic异常。

第5步:单元素访问与修改

格式为 数组名[索引]。支持读取和直接赋值修改。

package main

import "fmt"

func main() {
	var a [2]int
	a[0] = 100
	a[1] = 200

	fmt.Printf("Original: a[0]=%d, a[1]=%d\n", a[0], a[1])

	// 修改元素
	a[0] = 1
	a[1] = 2
	fmt.Printf("Modified: a[0]=%d, a[1]=%d\n", a[0], a[1])
}

第6步:常规 For 循环遍历

利用 len() 获取长度,通过索引逐个访问。适用于需要同时知道索引和值的场景。

package main

import "fmt"

func main() {
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	for i := 0; i < len(arr); i++ {
		fmt.Printf("Index: %d, Value: %d\n", i, arr[i])
	}
}

第7步:Range 快捷遍历

for range 是Go特有的迭代语法,能同时返回索引和下标对应的值。若不需要索引,可使用空白标识符 _ 忽略。

package main

import "fmt"

func main() {
	arr := [...]int{1, 2, 3, 4, 5}
	// 仅取值
	for _, v := range arr {
		fmt.Println(v)
	}

	// 取值和索引
	for i, v := range arr {
		fmt.Printf("Index %d is %d\n", i, v)
	}
}

四、数组实战应用案例

第8步:业务逻辑中的数据清洗(成绩录入)

场景:录入10名学生成绩,要求低于60分的强制设为60分。

package main

import "fmt"

func main() {
	var scores [10]float32
	var s float32

	for i := 0; i < 10; i++ {
		fmt.Printf("请输入第%d名学生的成绩:", i+1)
		fmt.Scan(&s)
		if s < 60 {
			scores[i] = 60
		} else {
			scores[i] = s
		}
	}

	fmt.Println("录入完成,清单如下:")
	for j := 0; j < 10; j++ {
		fmt.Printf("第%d名: %.0f\n", j+1, scores[j])
	}
}

第9步:数值处理(求最大值)

通过一次遍历对比,找出数组中的最大值。

package main

import "fmt"

func main() {
	numbers := [5]int{0, 0, 0, 0, 0}
	for i := 0; i < 5; i++ {
		var n int
		fmt.Printf("输入第%d个数字: ", i+1)
		fmt.Scan(&n)
		numbers[i] = n
	}

	maxVal := numbers[0]
	for k := 1; k < 5; k++ {
		if numbers[k] > maxVal {
			maxVal = numbers[k]
		}
	}
	fmt.Println("最大值:", maxVal)
}

第10步:经典算法(冒泡排序)

冒泡排序通过重复遍历列表,比较相邻元素并交换,直到列表有序。以下是针对随机输入的整数数组实现排序:

package main

import "fmt"

func main() {
	var numbers []int
	for i := 0; i < 5; i++ {
		var val int
		fmt.Printf("输入第%d个数: ", i+1)
		fmt.Scan(&val)
		numbers = append(numbers, val)
	}

	fmt.Println("排序前:", numbers)
	// 外层控制轮数,内层控制比较次数
	for j := 0; j < len(numbers)-1; j++ {
		for i := 0; i < len(numbers)-j-1; i++ {
			if numbers[i] > numbers[i+1] {
				// 交换元素
				numbers[i], numbers[i+1] = numbers[i+1], numbers[i]
			}
		}
	}
	fmt.Println("排序后:", numbers)
}

五、多维数组的处理

Go支持多维数组,最常用的是二维数组(矩阵)。它本质上是一个由一维数组组成的数组。

第11步:二维数组的定义与初始化

声明时需指明两个维度的长度:[行][列]类型。

// 固定长度声明
var matrix [3][4]int

// 复合字面量初始化
matrix := [3][4]int{
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11},
}

第12步:动态拼接与不规则二维数组

若各行长度不一致,建议使用切片 [][]type 配合 append 函数,这比固定数组更灵活。

package main

import "fmt"

func main() {
	// 创建一个空的切片二维数组
	list := [][]string{}

	row1 := []string{"A", "B", "C"}
	row2 := []string{"D"}

	list = append(list, row1, row2)
	fmt.Println(list) // [[A B C] [D]]
}

第13步:访问与嵌套遍历

使用双重循环访问每个元素,或通过坐标 a[i][j] 精确取值。

package main

import "fmt"

func main() {
	nums := [2][3]int{
		{1, 2, 3},
		{4, 5, 6},
	}
	for i := 0; i < 2; i++ {
		for j := 0; j < 3; j++ {
			fmt.Printf("[%d][%d]: %d\n", i, j, nums[i][j])
		}
	}
}

六、数组作为函数参数传递

Go语言中,数组是值拷贝传递的。这意味着在函数内部修改数组元素不会影响到原数组(除非传入数组指针),但需注意函数签名必须匹配数组长度。

第14步:传递固定长度数组

形参必须严格指定长度,例如 [5]int。否则编译器会报错,因为 [5]int 和 [3]int 被视为不同类型。

package main

import "fmt"

// 注意形参类型为 [5]int
func calculateSum(arr [5]int) int {
	sum := 0
	for _, v := range arr {
		sum += v
	}
	return sum
}

func main() {
	data := [5]int{10, 20, 30, 40, 50}
	fmt.Println("总和:", calculateSum(data))
}

第15步:传递切片以解决长度限制

在实际工程中,通常建议将数组转换为切片 []int 传入函数,这样无需关心数组的具体长度,更加通用。

func getAverage(arr []int) float64 {
    // 处理逻辑...
    return avg
}

以上就是Go语言学习之数组的用法详解的详细内容,更多关于Go语言数组的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表