改变一个二维数组变量会同时改变原始的二维数组变量。为什么会这样呢?

huangapple go评论66阅读模式
英文:

Changing a 2D array variable changes the original 2D array variable as well. Why?

问题

为什么矩阵也会改变呢?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]]
}
英文:

Why is matrix change as well? Go variables are passed or copied by value, not reference unless explicitly specified using pointers vs values. Is there something that I don't understand?


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]]
}

答案1

得分: -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 slices are references to an underlying array. A slice is like a pointer to a value, not like a direct value. If you use arrays instead of slices, you will see different behavior:

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)
}

Output:

[[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]]

You can see that because I used an array [5][5]int of arrays [5]int instead of a slice [][]int of slices []int, the assignment matrix2 = matrix made a copy of the entire matrix.

If you want to use a variable-size matrix, you will have to write your own function to create matrix copies. The above code only works if you know the size of your matrix at compile-time (e.g. 5x5).

huangapple
  • 本文由 发表于 2021年9月6日 06:41:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/69067684.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定