代码如下:
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)
}
我知道代码错误,因为for循环变量在for-range循环中重用。
当goroutine有机会启动时,v
的值可能已被修改。所以打印结果为"three,three,three"
。
但是当我们将数据变量修改为另一个声明时:
data := []*field{{"one"},{"two"},{"three"}}
打印结果为"one ,two,three"
。
我没有明白为什么。指针是否有任何不同或者是否有任何不同的机制?
我是从this article读到的。但海报并没有说明原因。或者只是输出正确的事件。
答案 0 :(得分:1)
在第一个循环中,v
是field
项的值。由于v
是可寻址的,因此它会自动被引用为print()
方法的指针接收器。所以v.print()
正在使用v
本身的地址,并且每次迭代循环都会覆盖该地址的内容。
当您更改声明以使用*field
时,v
现在是指向field
值的指针。在这种情况下,当您致电v.print()
时,您正在使用v
指向的值进行操作,该值存储在data
中,并且覆盖v
无效。