Reputation: 147
The code is like the following:
package main
import (
"fmt"
"time"
)
type field struct {
name string
}
func (p *field) print() {
fmt.Println(p.name)
}
func main() {
data := []field{{"one"},{"two"},{"three"}}
for _,v := range data {
go v.print()
}
time.Sleep(3 * time.Second)
}
I know that the code is wrong,because the for loop variable is reused in the for-range loop.
When the goroutine has got the chance to launch,the value of v
might has been modified. so the print result will be "three,three,three"
.
But when we modify the data variable into another declaration as:
data := []*field{{"one"},{"two"},{"three"}}
the print result will be "one ,two,three"
.
I didn't get the point of why. Does the pointer make any difference or any different mechanism is on this?
I read this from this article. But the poster didn't not tell why. Or it's just a incident the output is right.
Upvotes: 1
Views: 774
Reputation: 109426
In the first loop, v
is the value of a field
item. Because v
is addressable, it is automatically referenced as the pointer receiver for the print()
method. So v.print()
is using the address of v
itself, and the contents of that address is overwritten each iteration of the loop.
When you change the declaration to use a *field
, v
is now a pointer to a field
value. When you call v.print()
in this case, you are operating on the value that v
points to, which is stored in data
, and the overwriting of v
has no effect.
Upvotes: 1