
Go 语言中,数组类型变量的赋值(如 a[0] = a[1])是深拷贝:整个数组元素被逐字节复制到目标内存位置,新数组与原数组完全独立,互不影响。
go 语言中,数组赋值是深拷贝:整个数组元素被逐字节复制到目标内存位置,新数组与原数组完全独立,互不影响。
在 Go 中,数组(array)是值类型,其大小在编译期确定,且内存布局是连续、固定的。这意味着每个数组变量都拥有自己独占的一块内存空间,不共享底层数据。
以题目中的二维数组为例:
var a [2][3]int a[0][0] = 55; a[0][1] = 56; a[0][2] = 57 a[1][0] = 65; a[1][1] = 66; a[1][2] = 67
此时 a 在内存中实际是一段连续的 6 个 int(假设 int 为 8 字节,则共 48 字节),布局如下:
[55 56 57 65 66 67] ↑a[0]↑ ↑a[1]↑
执行 a[0] = a[1] 后,Go 将 a[1] 所含的 3 个 int 值(65, 66, 67)完整复制到 a[0] 对应的内存区域。结果是:
[65 66 67 65 66 67] ↑a[0]↑ ↑a[1]↑
✅ a[0] 和 a[1] 各自持有独立的 3 个整数值;修改 a[0][0] 不会影响 a[1][0],反之亦然。
⚠️ 注意:这与 切片(slice)截然不同。切片是引用类型,底层包含指向底层数组的指针、长度和容量。对切片的赋值只是复制这三个字段(浅拷贝),因此多个切片可能共享同一底层数组——修改一个切片的元素可能影响另一个。
例如对比:
s1 := []int{1, 2, 3}
s2 := s1 // 浅拷贝:s1 和 s2 共享底层数组
s2[0] = 99
fmt.Println(s1) // 输出 [99 2 3] —— 被意外修改!
而数组则安全得多:
arr1 := [3]int{1, 2, 3}
arr2 := arr1 // 深拷贝:完全独立副本
arr2[0] = 99
fmt.Println(arr1) // 输出 [1 2 3] —— 未受影响
✅ 总结:
- Go 中所有数组赋值(包括多维数组的行赋值,如
a[0] = a[1])均为深拷贝; - 拷贝开销与数组大小成正比(大数组需谨慎);
- 若需共享数据或追求高效传递,应使用切片或指针;
- 理解“数组是值类型”是掌握 Go 内存语义的关键基础。










