Go语言数组全面解析:定义、初始化与实战应用
本文详细介绍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语言数组的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













