
本文详解 go 语言中使用切片模拟二维数组时,因复用底层底层数组导致 append 出现数据覆盖的问题,并提供正确创建独立行切片的解决方案。
本文详解 go 语言中使用切片模拟二维数组时,因复用底层底层数组导致 append 出现数据覆盖的问题,并提供正确创建独立行切片的解决方案。
在 Go 中,[][]int 并非传统意义上的“二维数组”,而是一个切片的切片——即外层切片存储的是多个 []int 类型的引用(包含指向底层数组的指针、长度和容量)。关键在于:如果多次 append 的是同一个切片变量(共享同一底层数组),那么后续对该变量的修改会反映在所有已 append 的位置上。
你原始代码的问题根源正在于此:
row := make([]int, n) // ✅ 只在循环外创建一次!
for _, _ = range row {
for j := range row {
fmt.Scanf("%d", &row[j])
}
array = append(array, row) // ❌ 每次 append 的都是同一个 row 变量的引用
}
虽然 row 的值在每次内层循环后看似不同(如 [1 2] → [3 4]),但 array 中存储的两个元素实际指向同一块内存地址。当第二次读入 3 4 时,row 底层数组被覆写,之前 append 进去的 row 引用也随之“看到”新值,最终 array 中两个子切片都显示 [3 4]。
✅ 正确做法是:每次迭代都创建全新的切片,确保各行拥有独立的底层数组:
func main() {
var n int
fmt.Scanf("%d", &n)
array := [][]int{}
for i := 0; i <p>? 关键概念总结:</p>
- Go 切片是引用类型,赋值或传参时复制的是头信息(指针+len+cap),不是底层数组;
- append 不改变原切片变量,但若目标切片容量足够,可能复用原底层数组;
- 要保证逻辑上的“深拷贝”行为(如二维结构各行独立),必须为每一行显式调用 make([]int, n) 创建新切片;
- 若需更安全的模式,可考虑使用 copy() 或 append([]int(nil), row...) 显式复制,但本例中直接重建更清晰高效。
运行修正后的代码输入:
2 1 2 3 4
将准确输出:
Printing current Row [1 2] Printing current Array [[1 2]] Printing current Row [3 4] Printing current Array [[1 2] [3 4]] Final Array [[1 2] [3 4]]
牢记:在构建多维切片时,“每层维度都应独立分配”,这是避免意外共享状态的核心原则。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











