Go语言修改赋值后的二维切片变量原变量同步变更是什么原因
问题解答
核心误区澄清
你对Go默认值传递的规则理解是正确的,Go语言中所有的赋值、参数传递都是值拷贝,不存在引用传递,出现这个现象的核心原因是你混淆了「切片类型的结构」和「值拷贝的范围」:
- Go的切片(
slice)本质是一个内置结构体,内部仅存三个字段:指向底层数组的指针、切片长度、切片容量,切片本身不存储实际的元素数据。 - 你声明的
matrix是[][]int类型,也就是外层是切片,外层切片的每个元素也是切片。当执行matrix2 = matrix时,确实做了值拷贝:拷贝的是外层切片的结构体内容,包括外层切片的指针、长度、容量,所以拷贝后的matrix2和原matrix指向同一个外层底层数组,而这个外层底层数组存的就是每个内层切片的结构体,内层切片的指针也还是指向原来的内层底层数组。 - 你修改
matrix2[0][1]的时候,实际是通过matrix2[0]这个内层切片的指针,修改它指向的内层底层数组的元素,原matrix[0]指向的是同一个底层数组,自然会同步变化。
验证方案
你可以用以下两种方式验证规则:
- 用数组而非切片测试:数组是纯值类型,赋值会完整拷贝所有元素,修改新数组不会影响原数组
import "fmt" func main() { arr := [5]int{100, 20, 30, 10, 11} arr2 := arr arr2[1] = 11111111 fmt.Println(arr) // 输出 [100 20 30 10 11] 原数组不变 fmt.Println(arr2) // 输出 [100 11111111 30 10 11] }
- 二维切片深拷贝实现:如果要得到完全独立的二维切片,需要逐层拷贝每个内层切片的底层数据
import "fmt" func deepCopy2DSlice(src [][]int) [][]int { dst := make([][]int, len(src)) for i := range src { dst[i] = make([]int, len(src[i])) copy(dst[i], src[i]) } return dst } func main() { matrix := [][]int{ {100, 20, 30, 10, 11}, {15, 100, 16, 4, 2}, } matrix2 := deepCopy2DSlice(matrix) matrix2[0][1] = 11111111 fmt.Println(matrix) // 输出 [[100 20 30 10 11] [15 100 16 4 2]] 原切片不变 fmt.Println(matrix2) // 输出 [[100 11111111 30 10 11] [15 100 16 4 2]] }
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

