

新闻资讯
技术教程因为Go中数组是值类型,传参时会复制整个数组,函数内修改不影响原数组;需用数组指针(*[3]int)或切片([]int)才能修改原数据。
Go 语言中,array 是值类型。当你把一个数组(比如 [3]int)作为参数传给函数时,实际上传的是整个数组的副本。函数内部对它的任何修改,都不会影响调用方的原始数组。
常见错误现象:
func modify(arr [3]int) {
arr[0] = 999
}
a := [3]int{1, 2, 3}
modify(a)
// a 还是 [1 2 3],没变
这不是 bug,是 Go 的设计选择:数组大小固定、可比较、适合栈上分配。但这也意味着——想改原数组,必须绕过值拷贝。
最直接的方式是传指向数组的指针,比如 *[3]int。这时函数接收的是地址,解引用后可直接写原内存。
[3]),因为 [3]int 和 [4]int 是完全不同的类型&a 取地址,不能漏掉 &
(*arr)[i] 或更常见的 arr[0](Go 允许对数组指针直接下标访问)操作实操示例:
func modifyPtr(arr *[3]int) {
arr[0] = 999 // 等价于 (*arr)[0] = 999
}
a := [3]int{1, 2, 3}
modifyPtr(&a)
// a 现在是 [999 2 3]
绝大多数场景下,你真正需要的不是“修改固定长度数组”,而是“修改一段连续数据”。这时应优先用 []int(切片),它底层包含指向底层数组的指针、长度和容量。
立即学习“go语言免费学习笔记(深入)”;
切片是引用类型(本质是结构体,含指针字段),传参时只拷贝这个小结构体,不影响语义上的“可修改原数据”。
func modifySlice(s []int),无需写死长度a[:](从数组转切片)或原生切片变量append 可能导致底层数组扩容,此时原数组不受影响示例:
a := [3]int{1, 2, 3}
modifySlice(a[:]) // 传切片视图
// a 被修改了
func modifySlice(s []int) {
if len(s) > 0 {
s[0] = 999 // ✅ 影响原数组
}
}
新手常把 *[3]int 当成“类似 C 的 int*”,结果发现不能用 len()、不能遍历、甚至传错类型。
*[3]int 不是切片,不能直接用 range,也不能调用 len() 或 cap() —— 必须先解引用:len(*arr)
func f(arr *[3]int) 却传 &[]int{1,2,3}:类型不匹配,编译失败append 总是修改原数组:其实当容量不足时会分配新底层数组,原数组不变type T struct { Data *[1024]byte } 会把整个 1KB 数组塞进结构体,通常应改用 []byte 或 *[1024]byte 配合 make 分配复杂点在于:Go 没有“动态数组”原生类型,数组和切片语义分离。选哪种,取决于你是否需要编译期长度检查、是否涉及 cgo、是否追求极致栈分配
——大多数业务代码,用切片就够了,别硬套数组指针。