答:在调用函数之前先评估参数。在对它们进行评估之后,调用的参数将按值传递给函数,并且被调用函数开始执行,因此:
第一
go v.print()是语法糖
go (*field).print(&v)和
所述第二
go v.print()是语法糖
go (*field).print(v)。
如果
for在goroutines启动之前第一个循环完成,
&v则调用相同,这三个调用都相同。通过
time.Sleep(100)在
gov.print()第一个循环之后添加,请参见代码2 。或
go func(v field) { v.print() }(v)在The GoPlayground(带有的代码3
sync.WaitGroup)上使用。
另外,您在这里有 数据竞赛 (请参阅B)。
而对于第二个
go (*field).print(v)位置
v是之前调用参数评估真实指针和三个够程
1-在The Go Playground上尝试:
package mainimport ( "fmt" "time")type field struct { name string}func (p *field) print() { fmt.Println(p.name)}func main() { fmt.Println("use values:") // use values in range loop and go rountines values := []field{{"one"}, {"two"}, {"three"}} for _, v := range values { fmt.Println(&v) go (*field).print(&v) //go v.print() } time.Sleep(time.Second) fmt.Println() fmt.Println("use pointers:") // use pointers in range loop and go rountines poniters := []*field{{"one"}, {"two"}, {"three"}} for _, v := range poniters { fmt.Println(v) go (*field).print(v) //go v.print() } time.Sleep(time.Second)}输出:
use values:&{one}&{two}&{three}threethreethreeuse pointers:&{one}&{two}&{three}twoonethree2-在Go Playground上尝试:
package mainimport ( "fmt" "time")type field struct { name string}func (p *field) print() { fmt.Println(p.name)}func main() { fmt.Println("use values:") // use values in range loop and go rountines values := []field{{"one"}, {"two"}, {"three"}} for _, v := range values { fmt.Println(&v) go v.print() //go (*field).print(&v) // time.Sleep(100) } time.Sleep(time.Second) fmt.Println() fmt.Println("use pointers:") // use pointers in range loop and go rountines poniters := []*field{{"one"}, {"two"}, {"three"}} for _, v := range poniters { fmt.Println(v) go v.print() //go (*field).print(v) // } time.Sleep(time.Second)}输出:
use values:&{one}one&{two}two&{three}threeuse pointers:&{one}&{two}&{three}onetwothreeB:您之间存在数据争夺,请尝试
go build -race
您的代码,然后运行生成的文件
WARNING: DATA RACE:
输出:
use values:==================WARNING: DATA RACERead at 0x00c042030210 by goroutine 6: runtime.convT2E() Go/src/runtime/iface.go:155 +0x0 main.(*field).print() .../m.go:14 +0x6cPrevious write at 0x00c042030210 by main goroutine: main.main() .../m.go:22 +0x1c3Goroutine 6 (running) created at: main.main() .../m.go:23 +0x204==================twothreethreeuse pointers:onetwothreeFound 1 data race(s)



