Go 将切片传递给函数

Go 将切片传递给函数,go,Go,我对功能的传递有一些困惑。以下是我读到的: 以下是我所理解的:slice是一个带有指向真实数据指针的结构;当我们向函数传递一个切片时,我们只是复制一个指针,但函数使用的数据与原始函数相同 这是我的密码: type Example struct { A int B string } func foo(d []Example) { for _, e := range d { e.B = "bye" } } func main() { a

我对功能的传递有一些困惑。以下是我读到的:

以下是我所理解的:slice是一个带有指向真实数据指针的结构;当我们向函数传递一个切片时,我们只是复制一个指针,但函数使用的数据与原始函数相同

这是我的密码:

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

我已将结构的切片传递给函数,并更改了函数中的结构。为什么主函数中有旧值?

因为它是结构的一部分,而不是指向结构的指针的一部分。执行时:

for _, e := range d
在循环中,
e
是切片中元素的副本;修改它不会修改切片中的内容。如果
d
是一个
[]*示例
,它将按照您的预期工作:

请特别注意,这与切片无关。如果是:

func foo(d Example) {
    d.B = "bye"
}
您可能会遇到同样的问题:函数正在修改结构的副本,因此调用方的副本不受函数内部发生的情况的影响

另一种不使用指针的潜在解决方案是修改切片内的值,而不是在元素的副本中:

func foo(d []Example) {
    for i := range d {
        d[i].B = "bye"
    }
}
此样式的工作示例: