go数组长度固定且为值类型,[3]int与[4]int是不同类型;定义需显式指定长度,传参会复制整个数组,越界访问易panic。

Go 语言里数组不是动态的,定义时长度就固定了
Go 的数组是值类型,长度是类型的一部分。这意味着 [3]int 和 [4]int 是两种完全不同的类型,不能互相赋值。很多人从 Python 或 JavaScript 转过来,第一反应是“怎么不能 push?”,其实 Go 里真没这个操作——数组就是一块固定大小的连续内存。
- 定义必须写明长度:
var a [5]int,不能写[ ]int(那是切片) - 初始化时若用字面量省略长度,编译器会自动推导:
b := [3]int{1, 2, 3}→ 类型是[3]int - 传参时整个数组会复制,大数组(比如
[1024 * 1024]int)传参开销明显,这时候该用切片或指针
数组和切片混用时最容易 panic:index out of range
错误常发生在把数组当成切片用,或者对切片做越界访问后误以为是数组问题。比如 a := [3]int{1,2,3}; s := a[:4] 就会直接 panic,因为底层数组只有 3 个元素,[:4] 超出容量。
- 数组访问下标检查在运行时,但编译器不报错;切片的 len/cap 可查,数组只能靠
len(a)获取长度 for i := 0; i 安全;但 <code>for i := 0; i 必 panic- 用
range最省心:for i, v := range a自动按len(a)迭代,不会越界
想扩容或增删元素?别硬刚数组,改用 []T 切片
数组本身不支持追加、截断、动态增长。所有“需要变长”的场景,都应该用切片。切片底层指向数组,但自带 len/cap 管理逻辑,append 会自动处理扩容(可能分配新底层数组)。
-
a := [3]int{1,2,3}; s := a[:]→ 得到一个 len=3、cap=3 的切片,指向原数组 -
s = append(s, 4)→ 此时 cap 不够,运行时分配新数组,s 指向新地址,原数组不受影响 - 如果确定要长期持有且频繁修改,直接声明切片:
s := make([]int, 0, 10),预分配 cap 避免多次 realloc
函数参数传数组指针才能避免拷贝
数组作为参数传入函数时,默认按值传递,整个数组内容被复制。对大数组来说,这既是性能坑,也容易让人误以为修改形参会影响实参(其实不会)。
- 想原地修改原数组,必须传指针:
func zero(a *[1000]int),然后用(*a)[i] = 0或直接a[i] = 0(Go 允许指针直接下标访问) - 传切片更常见也更轻量:
func zero(s []int),因为切片本身是小结构体(ptr+len/cap),传参成本固定 - 注意:即使传了数组指针,也不能改变数组长度——长度仍是类型的一部分,不可变
真正容易被忽略的是:当你写 var a [0]int,它合法但几乎无用;而 var s []int 是零值切片,可直接 append。数组的“零值”和“空值”概念跟切片完全不同,别凭经验类推。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











