way*_*are 2 go slice goroutine
我试图循环一片函数,然后调用其中的每个函数.但是我得到了奇怪的结果.这是我的代码:
package main
import (
"fmt"
"sync"
)
func A() {
fmt.Println("A")
}
func B() {
fmt.Println("B")
}
func C() {
fmt.Println("C")
}
func main() {
type fs func()
var wg sync.WaitGroup
f := []fs{A, B, C}
for a, _ := range f {
wg.Add(1)
go func() {
defer wg.Done()
f[a]()
}()
}
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
我以为它会调用函数A,B然后调用C但是我的输出只得到Cs.
C
C
C
Run Code Online (Sandbox Code Playgroud)
请提出错误及其背后的逻辑.我怎样才能获得理想的行为.
经典去骗局:)
官方围棋常见问题
for a, _ := range f {
wg.Add(1)
a:=a // this will make it work
go func() {
defer wg.Done()
f[a]()
}()
}
Run Code Online (Sandbox Code Playgroud)
你func() {}()是一个关闭的关闭a.并且a是所有go funcgo例程的共享,因为for循环重用相同的var(在内存中意味着相同的地址,因此相同的值),所以自然它们都看到了最后的值a.
解决方案要么a:=a在关闭之前重新声明(如上所述).这将创建新的var(内存中的新地址),然后每次调用都是新的go func.
或者将其作为参数传递给go函数,在这种情况下,您传递a类似值的副本:
go func(i int) {
defer wg.Done()
f[i]()
}(a)
Run Code Online (Sandbox Code Playgroud)
你甚至不需要去试用这个https://play.golang.org/p/nkP9YfeOWF,例如演示相同的问题.这里的关键是"关闭".