为什么我的 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()
}