【问题标题】:Passing slices to a function将切片传递给函数
【发布时间】:2018-06-15 14:25:10
【问题描述】:

我对 passign slice 的功能有些困惑。这是我读到的:

以下是我的理解: 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)
    }
}

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

【问题讨论】:

    标签: go


    【解决方案1】:

    因为它是一个结构切片,而不是一个指向结构的指针切片。执行时:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      • 1970-01-01
      • 2017-09-18
      • 2017-02-10
      • 1970-01-01
      相关资源
      最近更新 更多