代码如下:
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"。
我不知道为什么。指针对此有什么影响或任何不同的机制吗?
我从这篇文章上读到这个。但海报没有说明原因。或者只是个意外,输出是对的。
发布于 2015-06-01 15:32:26
在第一个循环中,v是field项的值。因为v是可寻址的,所以它被自动引用为print()方法的指针接收器。因此,v.print()使用v本身的地址,并且该地址的内容在循环的每次迭代中都被覆盖。
当您将声明更改为使用*field时,v现在是指向field值的指针。在本例中调用v.print()时,您正在对v指向的值进行操作,该值存储在data中,而对v的覆盖没有任何效果。
https://stackoverflow.com/questions/30577212
复制相似问题