英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论