在 Go 中,使用 range 遍历二维切片时,迭代变量是元素的副本而非引用,直接赋值不会影响原切片;需通过索引(如 grid[i])显式赋值才能正确初始化子切片。
在 go 中,使用 `range` 遍历二维切片时,迭代变量是元素的副本而非引用,直接赋值不会影响原切片;需通过索引(如 `grid[i]`)显式赋值才能正确初始化子切片。
Go 的切片是引用类型,但其本身是包含底层数组指针、长度和容量的结构体值。当使用 for _, row := range grid 时,row 是 grid[i](即 []string)的一个独立副本——修改 row(例如 row = []string{"foo", "bar"})仅改变该局部变量,既不更新 grid[i],也不影响底层数组,因此编译器报错 row declared and not used。
✅ 正确做法是使用索引遍历,直接向 grid 的每个位置赋值:
grid := make([][]string, 2)
for i := range grid {
grid[i] = []string{"foo", "bar"}
}
fmt.Println(grid)
// 输出:[[foo bar] [foo bar]]
⚠️ 注意事项:
- make([][]string, 2) 仅分配了外层切片(长度为 2),每个元素初始为 nil []string,必须显式初始化每一行;
- 若需预分配每行容量,可进一步写成:grid[i] = make([]string, 2); grid[i][0], grid[i][1] = "foo", "bar";
- 避免 for _, v := range s { v = ... } 这类无副作用的赋值——Go 编译器会严格检查未使用变量。
总结:Go 中 range 提供的是只读副本语义,修改切片内容必须通过索引或指针;理解“切片头结构体值 + 底层数组引用”的双重特性,是掌握多维切片操作的关键。











