行业资讯

Go语言数组详解

发布时间:2026/8/2 16:58:13
Go语言数组详解 摘要本文参考菜鸟教程Go数组章节从零讲解数组定义、初始化、遍历、传参特性重点拆解入门头号误区数组长度属于类型、数组是值类型、数组与切片的本质差异配套完整可运行代码一、Go数组核心定义数组是长度固定、元素类型统一、内存连续的数据集合用于存放一组相同类型的数据。✅ 长度固定数组创建完成之后不能扩容、不能缩小✅长度是数组类型的一部分[5]int和[10]int是两种完全不同的数据类型类型不匹配无法赋值、传参、比较✅ 数组属于值类型。数组赋值、传入函数时会完整拷贝一份数据修改副本不会影响原始数组。拓展小知识内存连续意味着数组支持通过索引快速随机访问查询速度极快。二、数组声明与五种初始化方式2.1 基础语法var数组名[数组长度]数据类型示例定义长度为5的int数组vararr[5]int2.2 五种初始化写法方式1仅声明自动初始化为零值Go不存在无默认值的数组声明之后全部填充对应类型零值int→0string→bool→false指针→nil。packagemainimportfmtfuncmain(){vararr[5]intfmt.Println(arr)// [0 0 0 0 0]}方式2完整初始化所有元素// var标准写法vararr1[5]int[5]int{1,2,3,4,5}// 短变量声明开发常用arr2:[5]int{1,2,3,4,5}fmt.Println(arr1)fmt.Println(arr2)方式3使用...自动推导长度不想手动填写数组长度可以使用...编译器自动统计元素个数确定数组长度。arr:[...]int{10,20,30,40}fmt.Println(len(arr))// 4⚠️易错提醒...只能用于数组切片不能使用多维数组仅最外层支持...内层数组不允许。方式4指定下标局部初始化只给指定索引赋值其余位置自动填充零值。适合稀疏数组场景。arr:[5]int{1:666,3:888}fmt.Println(arr)// [0 666 0 888 0]方式5部分初始化剩余补零初始化元素数量少于数组长度未赋值位置自动填充零值。arr:[5]int{1,2}fmt.Println(arr)// [1 2 0 0 0]❌编译错误提醒初始化元素总数不能大于数组定义长度否则直接编译失败。三、数组访问与遍历3.1 通过索引访问元素数组下标从0开始合法区间0 ~ len(arr)-1funcmain(){arr:[3]int{11,22,33}fmt.Println(arr[0])// 11fmt.Println(arr[2])// 33}⚠️致命坑索引越界不会出现编译警告运行时直接触发panic程序异常崩溃编码时一定要注意边界3.2 两种遍历方式普通for循环依靠下标遍历适用场景需要手动控制遍历起点、终点、步长arr:[3]int{100,200,300}fori:0;ilen(arr);i{fmt.Printf(下标%d值%d\n,i,arr[i])}for range遍历日常优先推荐语法简洁适合完整遍历整个数组arr:[3]int{100,200,300}// 同时接收下标与数值foridx,val:rangearr{fmt.Println(idx,val)}// 不需要下标使用空白标识符 _ 舍弃避免变量未使用编译报错for_,val:rangearr{fmt.Println(val)}补充range遍历数组时每次循环得到的val是数组元素的拷贝修改val无法改变原数组内容。四、数组传参大坑值类型拷贝核心结论数组是值类型函数传参时会完整拷贝整个数组修改副本无法影响原数组。错误演示packagemainimportfmtfuncchangeArr(arr[3]int){arr[0]999}funcmain(){arr:[3]int{1,2,3}changeArr(arr)fmt.Println(arr)// [1 2 3]原值没有任何变化}原理传入函数内的只是原数组的拷贝函数操作的是全新副本和外部数组内存相互独立。额外性能隐患如果数组长度很大完整拷贝会造成大量内存开销严重影响性能两种可行解决方案方案1传递数组指针传递数组地址函数内部操作原始数组内存funcchangeArr(arr*[3]int){arr[0]999// Go语法糖可以不用写(*arr)[0]}funcmain(){arr:[3]int{1,2,3}changeArr(arr)fmt.Println(arr)// [999 2 3]}缺点数组指针依旧绑定固定长度通用性很差。方案2数组转为切片项目开发首选开发中基本不会使用数组指针更推荐把数组转为切片传递摆脱固定长度限制。funcchangeSlice(s[]int){s[0]999}funcmain(){arr:[3]int{1,2,3}changeSlice(arr[:])// arr[:] 将数组转为切片fmt.Println(arr)// [999 2 3]}五、数组比较规则Go数组支持、!比较但有严格限制只有长度相同、元素类型相同的两个数组才允许比较长度不一致直接触发编译错误因为二者不属于同一种类型。补充数组不支持 、 、 、大小比较funcmain(){a:[2]int{1,2}b:[2]int{1,2}c:[3]int{1,2,3}fmt.Println(ab)// true// fmt.Println(a c) 编译报错类型不一致}六、多维数组拓展实际开发偶尔会用到二维数组简单示例packagemainimportfmtfuncmain(){// 2行3列二维数组arr:[2][3]int{{1,2,3},{4,5,6},}fmt.Println(arr[0][1])// 2}重点多维数组依然遵守规则[2][3]int和[3][2]int是两种不同类型。七、数组 vs 切片核心对比特性数组 [N]T切片 []T长度固定不变长度属于类型一部分长度动态支持append扩容类型兼容[5]int 和 [10]int 是不同类型同类型切片之间完全兼容传参机制值传递完整拷贝大数据下性能差引用语义共享底层数组开销小比较运算支持、!不支持直接使用比较nil除外开发场景极少使用仅元素固定场景绝大多数业务场景首选八、零基础高频易错点汇总[5]int和[10]int属于不同类型不能赋值、传参、比较数组是值类型赋值、传参都会产生拷贝修改副本不会影响原数组大数组直接传递性能低下优先使用数组指针或者转为切片数组长度固定无法动态扩容业务开发优先选择切片数组索引越界不会编译报错运行直接触发panic程序崩溃...自动推导长度语法仅适用于数组切片、多维数组内层不能使用数组初始化元素数量不能超过数组定义长度数组未赋值的元素自动填充对应类型零值range遍历数组循环变量val是拷贝值修改val无法更改原数组数组仅支持 和 !不能使用大于小于进行比较。九、文末总结Go数组三大核心特点定长、值类型、长度参与类型构成一定要抛开其他语言数组的固有思维数组直接传参会发生完整拷贝如果需要修改原始数据推荐转为切片数组只适合元素数量固定不变的场景真实项目99%场景使用切片数组是理解切片的基础弄懂数组后续学习切片会轻松很多。参考资料菜鸟教程 Go语言数组 https://www.runoob.com/go/go-arrays.html