为什么我的 for 循环没有正确循环元素?
Why is my for loop not looping the elements right?
从可变参数函数和 WaitGroup 的 gobyexample 开始,我想出了这个 运行 一些函数作为并行和同步的 goroutines(打印仅调试):
package main
import (
"fmt"
"sync"
"time"
)
func WaitForFuncs(funcs ...func()) {
fmt.Print("funcs are: ", funcs, "\n")
var wg sync.WaitGroup
for _, f := range funcs {
fmt.Print("f is: ", f, "\n")
wg.Add(1)
go func() {
defer wg.Done()
f()
}()
}
wg.Wait()
}
func main() {
num := 4
WaitForFuncs(
func() {
fmt.Printf("Worker foo starting, num=%d\n", num)
time.Sleep(time.Second)
fmt.Printf("Worker foo done\n")
},
func() {
fmt.Printf("Worker bar starting\n")
time.Sleep(time.Second)
fmt.Printf("Worker bar done\n")
},
func() {
fmt.Printf("Worker baz starting\n")
time.Sleep(time.Second)
fmt.Printf("Worker baz done\n")
},
)
}
但是输出结果让我吃惊:
funcs are: [0x4a0360 0x4a0470 0x4a0540]
f is: 0x4a0360
f is: 0x4a0470
f is: 0x4a0540
Worker bar starting
Worker baz starting
Worker baz starting
Worker bar done
Worker baz done
Worker baz done
为什么打印 bar baz baz
而不是 foo bar baz
?
您必须在循环中使用中间变量,否则值在执行前会被覆盖。这就是为什么你只看到最后一个函数三次的原因。
func waitForFuncs(funcs ...func()) {
var wg sync.WaitGroup
for _, f := range funcs {
intermediate := f
wg.Add(1)
go func(inner func()) {
defer wg.Done()
inner()
}(intermediate)
}
wg.Wait()
}
从可变参数函数和 WaitGroup 的 gobyexample 开始,我想出了这个 运行 一些函数作为并行和同步的 goroutines(打印仅调试):
package main
import (
"fmt"
"sync"
"time"
)
func WaitForFuncs(funcs ...func()) {
fmt.Print("funcs are: ", funcs, "\n")
var wg sync.WaitGroup
for _, f := range funcs {
fmt.Print("f is: ", f, "\n")
wg.Add(1)
go func() {
defer wg.Done()
f()
}()
}
wg.Wait()
}
func main() {
num := 4
WaitForFuncs(
func() {
fmt.Printf("Worker foo starting, num=%d\n", num)
time.Sleep(time.Second)
fmt.Printf("Worker foo done\n")
},
func() {
fmt.Printf("Worker bar starting\n")
time.Sleep(time.Second)
fmt.Printf("Worker bar done\n")
},
func() {
fmt.Printf("Worker baz starting\n")
time.Sleep(time.Second)
fmt.Printf("Worker baz done\n")
},
)
}
但是输出结果让我吃惊:
funcs are: [0x4a0360 0x4a0470 0x4a0540]
f is: 0x4a0360
f is: 0x4a0470
f is: 0x4a0540
Worker bar starting
Worker baz starting
Worker baz starting
Worker bar done
Worker baz done
Worker baz done
为什么打印 bar baz baz
而不是 foo bar baz
?
您必须在循环中使用中间变量,否则值在执行前会被覆盖。这就是为什么你只看到最后一个函数三次的原因。
func waitForFuncs(funcs ...func()) {
var wg sync.WaitGroup
for _, f := range funcs {
intermediate := f
wg.Add(1)
go func(inner func()) {
defer wg.Done()
inner()
}(intermediate)
}
wg.Wait()
}