You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言修改赋值后的二维切片变量原变量同步变更是什么原因

问题解答

核心误区澄清

你对Go默认值传递的规则理解是正确的,Go语言中所有的赋值、参数传递都是值拷贝,不存在引用传递,出现这个现象的核心原因是你混淆了「切片类型的结构」和「值拷贝的范围」:

  • Go的切片(slice)本质是一个内置结构体,内部仅存三个字段:指向底层数组的指针、切片长度、切片容量,切片本身不存储实际的元素数据。
  • 你声明的matrix是[][]int类型,也就是外层是切片,外层切片的每个元素也是切片。当执行matrix2 = matrix时,确实做了值拷贝:拷贝的是外层切片的结构体内容,包括外层切片的指针、长度、容量,所以拷贝后的matrix2和原matrix指向同一个外层底层数组,而这个外层底层数组存的就是每个内层切片的结构体,内层切片的指针也还是指向原来的内层底层数组。
  • 你修改matrix2[0][1]的时候,实际是通过matrix2[0]这个内层切片的指针,修改它指向的内层底层数组的元素,原matrix[0]指向的是同一个底层数组,自然会同步变化。

验证方案

你可以用以下两种方式验证规则:

  1. 用数组而非切片测试:数组是纯值类型,赋值会完整拷贝所有元素,修改新数组不会影响原数组
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]
}
  1. 二维切片深拷贝实现:如果要得到完全独立的二维切片,需要逐层拷贝每个内层切片的底层数据
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 14:21:02