Go数组是固定长度、值语义的内存块,声明后不可扩容,赋值传参默认整体拷贝;[3]int与[4]int类型不同;支持直接比较但要求长度和元素完全一致;大数组应传指针避免拷贝;需动态操作时应使用切片。

Go 里的数组不是你习惯的“动态容器”,它是一块固定大小、值语义的内存块——用错场景或误当切片用,性能和逻辑都会出问题。
数组声明后长度不可变,且赋值是整体拷贝
Go 数组的长度是类型的一部分,[3]int 和 [4]int 是完全不同的类型。声明后无法扩容,也不能像切片那样通过 append 增长。
更关键的是:数组变量赋值或传参时默认按值拷贝整块内存:
func process(a [1024]int) { /* 拷贝 1024×8 = 8KB */ }
var x [1024]int
process(x) // 这里发生完整拷贝- 小数组(如
[2]string、[3]float64)传值没问题,编译器可能优化 - 大数组(≥ 数百元素)务必传指针:
func process(a *[1024]int),避免隐式拷贝 - 如果需要增删元素,直接用
[]T切片,别硬套数组
数组字面量和比较必须严格匹配长度与元素值
数组支持直接比较(==),但要求长度相同、每个位置元素相等。这是编译期确定的行为,和切片不同(切片不能直接比较)。
立即学习“go语言免费学习笔记(深入)”;
网趣购物系统静态版支持网站一键静态生成,采用动态进度条模式生成静态,生成过程更加清晰明确,商品管理上增加淘宝数据包导入功能,与淘宝数据同步更新!采用领先的AJAX+XML相融技术,速度更快更高效!系统进行了大量的实用性更新,如优化核心算法、增加商品图片批量上传、谷歌地图浏览插入等,静态版独特的生成算法技术使静态生成过程可随意掌控,从而可以大大减轻服务器的负担,结合多种强大的SEO优化方式于一体,使
常见陷阱:
var a = [3]int{1, 2, 3}
var b = [3]int{1, 2, 3}
fmt.Println(a == b) // true
var c = [4]int{1, 2, 3, 0}
fmt.Println(a == c) // 编译错误:mismatched types [3]int and [4]int
- 初始化时省略长度(
[...]int{1,2,3})会推导为[3]int,但结果仍是数组类型,不是切片 - 想用比较能力又需灵活性?考虑封装成结构体,把数组作为字段 + 自定义
Equal()方法 - JSON 解码到数组时,若字段数量不匹配会失败;而解码到切片则自动适配
性能敏感场景下,数组比切片更可控但更易误用
数组在栈上分配(除非逃逸),无头开销、无动态增长成本,适合已知尺寸、生命周期短的场景,比如哈希桶、固定缓冲区、SIMD 向量操作。
- 用
var buf [4096]byte做 I/O 缓冲比make([]byte, 4096)少一次堆分配,但注意:若函数内局部声明过大(如 >2KB),可能触发栈分裂甚至逃逸到堆 - 用
sync.Pool复用大数组时,要存*[8192]byte而非[8192]byte,否则每次 Get 都拷贝整块 - 循环中频繁取数组地址(
&a[i])没问题;但对切片做同样操作,底层数组可能被其他 goroutine 修改,需额外同步
真正难的不是语法,而是判断「这里到底该用数组还是切片」——看是否需要共享底层数组、是否允许动态伸缩、是否追求零分配,以及有没有人不小心把 [N]T 当成 []T 传给期望切片的函数。










