【问题标题】:Changing a 2D array variable changes the original 2D array variable as well. Why? [duplicate]更改 2D 数组变量也会更改原始 2D 数组变量。为什么? [复制]
【发布时间】:2021-11-03 03:19:56
【问题描述】:

为什么矩阵也会改变? Go 变量是按值传递或复制的,而不是引用,除非使用指针与值明确指定。有什么不明白的地方吗?


import "fmt"

func main() {
    matrix := [][]int{
        {100, 20, 30, 10, 11},
        {15, 100, 16, 4, 2},
        {3, 5, 100, 2, 4},
        {19, 6, 18, 100, 3},
        {16, 4, 7, 16, 100},
    }
    var matrix2 [][]int
    matrix2 = matrix
    matrix2[0][1] = 11111111
    fmt.Println(matrix)
    fmt.Println(matrix2)

    // Output :
    [[100 11111111 30 10 11] [15 100 16 4 2] [3 5 100 2 4] [19 6 18 100 3] [16 4 7 16 100]]
    [[100 11111111 30 10 11] [15 100 16 4 2] [3 5 100 2 4] [19 6 18 100 3] [16 4 7 16 100]]
}

【问题讨论】:

标签: go


【解决方案1】:

Go 切片是对底层数组的引用。切片就像指向值的指针,而不是直接值。如果你使用数组而不是切片,你会看到不同的行为:

package main
import "fmt"

func main() {
    matrix := [5][5]int{
        {100, 20, 30, 10, 11},
        {15, 100, 16, 4, 2},
        {3, 5, 100, 2, 4},
        {19, 6, 18, 100, 3},
        {16, 4, 7, 16, 100},
    }
    var matrix2 [5][5]int
    matrix2 = matrix
    matrix2[0][1] = 11111111
    fmt.Println(matrix)
    fmt.Println(matrix2)
}

输出:

[[100 20 30 10 11] [15 100 16 4 2] [3 5 100 2 4] [19 6 18 100 3] [16 4 7 16 100]]
[[100 11111111 30 10 11] [15 100 16 4 2] [3 5 100 2 4] [19 6 18 100 3] [16 4 7 16 100]]

您可以看到,因为我使用数组 [5][5]int 的数组 [5]int 而不是切片 [][]int 的切片 []int,所以赋值 matrix2 = matrix 复制了整个矩阵。

如果您想使用可变大小的矩阵,则必须编写自己的函数来创建矩阵副本。仅当您在编译时知道矩阵的大小(例如 5x5)时,上述代码才有效。

【讨论】:

  • 措辞不对。语言中没有引用之类的东西。引用 go.dev/blog/slices-intro A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacityarrays are values
  • 非常感谢。这回答了我的问题。 slice 是唯一类似于指向值的指针的类型,还是有其他类似的类型?
  • @mh-cbon:指针是对内存中某个位置的引用。
  • @mh-cbon:仔细区分“指针”和“引用”在 C++ 等语言中很有用,其中术语指的是不同的类型。在大多数其他语言中,例如 Java、Python 或 Go,没有必要区分“指针”和“引用”。
  • 是的,但是这个特定的词是模棱两可的。这是不合理的,切片内部的逻辑完全适合该语言,并且使用其词汇来解释它们的行为更充分。
猜你喜欢
  • 1970-01-01
  • 2019-07-27
  • 2012-04-30
  • 2015-01-07
  • 2020-10-04
  • 2018-04-16
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多