关于传递切片的功能,我有些困惑。以下是我所写的内容:
以下是我所理解的:切片是一个带有指向实际数据的指针的结构;当我们将一个切片传递给一个函数时,我们只是复制一个指针,但该函数使用与原始函数相同的数据。
这是我的代码:
type Example struct {
A int
B string
}
func foo(d []Example) {
for _, e := range d {
e.B = "bye"
}
}
func main() {
a := Example{}
a.A = 10
a.B = "hello"
b := Example{}
b.A = 10
b.B = "hello"
var c []Example
c = append(c, a)
c = append(c, b)
foo(c)
for _, e := range c {
fmt.Println(e.B)
}
}
我已经将一些结构传递给一个函数,并且已经更改了函数中的结构。为什么我在main函数中有旧值?
答案 0 :(得分:3)
因为它是结构的一部分,而不是结构的指针。执行时:
for _, e := range d
在循环内部,e
是来自切片的元素的副本;修改它不会修改切片中的内容。如果d
为[]*Example
,则会按预期运行:https://play.golang.org/p/4ZgLETpq6d0
特别注意,这与切片没有任何关系。如果是:
func foo(d Example) {
d.B = "bye"
}
你会遇到同样的问题:该函数正在修改结构的副本,因此调用者的副本不受函数内部发生的影响。
另一个不使用指针的潜在解决方案是修改切片中的值,而不是修改元素的副本:
func foo(d []Example) {
for i := range d {
d[i].B = "bye"
}
}