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.
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.
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.