Why are Slices insides structs "passed by reference" when passed into functions in Go?

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

Why are Slices insides structs "passed by reference" when passed into functions in Go?

问题

package main

import "fmt"

func main() {

    a := SomeType{myslice: []int{1, 2, 3}, decimal: 2.33}

    for _, i := range a.myslice {
        fmt.Println(i)
    }
    fmt.Println(a.decimal)

    addOne(a)

    for _, i := range a.myslice {
        fmt.Println(i)
    }
    fmt.Println(a.decimal)

}

type SomeType struct {
    myslice []int
    decimal float32
}

func addOne(s SomeType) {
    s.myslice[0]++
    s.decimal += 1.2
}

上述代码的输出结果为:

1
2
3
2.33
2
2
3
2.33

即使我没有通过引用传递 SomeType 对象 a,myslice 字段仍然在原始对象中被修改。为什么会发生这种情况?有没有办法在不创建原始对象的副本的情况下传递整个对象的值?

英文:
package main

import "fmt"

func main() {

	a := SomeType{myslice: []int{1, 2, 3}, decimal: 2.33}

	for _, i := range a.myslice {
		fmt.Println(i)
	}
	fmt.Println(a.decimal)

	addOne(a)

	for _, i := range a.myslice {
		fmt.Println(i)
	}
	fmt.Println(a.decimal)

}

type SomeType struct {
	myslice []int
	decimal float32
}

func addOne(s SomeType) {
	s.myslice[0]++
	s.decimal += 1.2
}

The output for the code above is:

1
2
3
2.33
2
2
3
2.33

Even though i have not passed the SomeType object a by reference the myslice field is being modified in the original object. Why is this happening? Is there anyway to pass the entire object by value without having to create a copy of the original object?

答案1

得分: 2

这里的切片并不是真正通过引用进行传递;如果你在addOne函数中对其进行追加操作,它的长度不会改变。但是,切片包含对其支持数组的引用(或指针)。因此,当你复制一个切片时,新的切片与旧的切片共享同一个支持数组。

切片位于结构体内部并不会有任何区别。如果你将addOne函数改为只接受一个切片而不是整个结构体,你会看到相同的结果。

英文:

The slice is not really being passed by reference; if you append to it in addOne, its length will not change. But a slice contains a reference (or pointer) to its backing array. So when you copy a slice, the new one shares the same backing array with the old one.

The fact that the slice is inside a struct doesn't make any difference. You would see the same thing if you changed addOne to just take a slice instead of the whole struct.

huangapple
  • 本文由 发表于 2017年1月29日 01:25:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/41912662.html
匿名

发表评论

匿名网友

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

确定