将切片传递给函数

时间:2018-01-05 18:27:20

标签: go

关于传递切片的功能,我有些困惑。以下是我所写的内容:

enter image description here

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

这是我的代码:

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函数中有旧值?

1 个答案:

答案 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"
    }
}

此款式的工作示例:https://play.golang.org/p/_UJGU0XqaUO