
在 go 中使用切片模拟二维数组时,若重复复用同一底层数组的切片变量并 append 到外层切片,会导致所有元素指向相同内存地址,从而出现数据覆盖与重复现象。
在 go 中使用切片模拟二维数组时,若重复复用同一底层数组的切片变量并 append 到外层切片,会导致所有元素指向相同内存地址,从而出现数据覆盖与重复现象。
Go 的切片(slice)本身是引用类型,它包含三个字段:指向底层数组的指针、长度(len)和容量(cap)。当你执行 array = append(array, row) 时,实际追加的是对 row 底层数组的引用,而非其值的深拷贝。因此,如果后续修改了 row 所指向的同一块内存(例如再次调用 make([]int, n) 未重新分配),之前 append 进去的切片也会随之“更新”——这正是问题中 [[3 4] [3 4]] 输出的根本原因。
关键在于:每次循环必须创建全新的切片实例,确保每个子切片拥有独立的底层数组。修正后的代码将 row := make([]int, n) 移入 for 循环内部,从而为每一行分配独立内存:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
func main() {
var n int
fmt.Scanf("%d", &n)
array := [][]int{}
for i := 0; i <p>⚠️ 注意事项:</p>
- 不要将 make([]int, n) 提前声明在循环外(如原代码中的 row := make(...) 在循环前),否则所有 append 都共享同一底层数组;
- 若需高性能或大量数据操作,可考虑预分配 array := make([][]int, 0, n) 提升效率;
- 更安全的做法是显式复制(如 append([]int(nil), row...)),但本例中新建切片已足够;
- Go 没有原生多维数组语法([n][m]int 是数组,非动态切片),务必区分 [2][3]int(固定大小数组)与 [][]int(动态二维切片)。
总结:理解切片的引用语义是避免此类 bug 的核心——append 从不自动复制底层数组,开发者必须主动确保每个被 append 的切片具有独立内存空间。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










