在范围循环中调用结构体方法。

huangapple go评论91阅读模式
英文:

Call struct method in range loop

问题

为什么以下代码中:

for x, _ := range body.Personality {
    body.Personality[x].Mutate()
}

成功地改变了结构体的内容,但是以下代码却没有:

for _, pf := range body.Personality{
    pf.Mutate()
}

是因为range在迭代每个元素时创建了新的实例吗?因为结构体确实发生了变化,但变化并没有持久化。

英文:

example code (edited code snippet): http://play.golang.org/p/eZV4WL-4N_

Why is it that

for x, _ := range body.Personality {
    body.Personality[x].Mutate()
}

successfully mutates the structs' contents, but

for _, pf := range body.Personality{
    pf.Mutate()
}

does not?
Is it that range creates new instances of each item it iterates over? because the struct does in fact mutate but it doesn't persist.

答案1

得分: 2

range关键字会复制数组的结果,因此使用range的值无法修改原始数组的内容。如果你想修改原始的数组/切片,你必须使用索引或指针的切片。

这种行为在规范中有所涵盖,如这里所述。关键点在于赋值语句x := a[i]会将a[i]的值复制给x,因为它不是指针。由于range被定义为使用a[i],所以这些值会被复制。

英文:

The range keyword copies the results of the array, thus making it impossible to alter the
contents using the value of range. You have to use the index or a slice of pointers instead of values
if you want to alter the original array/slice.

This behaviour is covered by the spec as stated here. The crux is that an assignment line
x := a[i] copies the value a[i] to x as it is no pointer. Since range is defined to use
a[i], the values are copied.

答案2

得分: 1

你的第二个循环大致等同于:

for x := range body.Personality {
    pf := body.Personality[x]
    pf.Mutate()
}

由于body.Personality是一个结构体数组,对pf的赋值会创建结构体的副本,然后我们在副本上调用Mutate()方法。

如果你想以与示例中相同的方式遍历数组,一种选择是将其定义为结构体指针的数组(即[]*PFile)。这样,在循环中的赋值操作将只是取结构体的指针,从而允许你修改它。

英文:

Your second loop is roughly equivalent to:

for x := range body.Personality {
    pf := body.Personality[x]
    pf.Mutate()
}

Since body.Personality is an array of structs, the assignment to pf makes a copy of the struct, and that is what we call Mutate() on.

If you want to range over your array in the way you do in the example, one option would be to make it an array of pointers to structs (i.e. []*PFile). That way the assignment in the loop will just take a pointer to the struct allowing you to modify it.

huangapple
  • 本文由 发表于 2013年9月20日 05:25:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/18905187.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定