异步与函数引用外部变量的问题

原因就是因为是异步的,循环会首先执行结束,再去执行函数

如果循环次数比较少的话,那么函数所引用的外部变量就会变成最后一个值,在函数f1中,就是全部是c

所以可以想象的是,如果循环特别多的话,那么会有一部分函数引用的变量是一样的,结果就是输出很多个 x,再输出很多个 x+1…,如函数f3

解决这个问题的方法就是,不要在函数内部直接引用外部变量,而是显式的传递参数,如函数f2

package main

import (
    "fmt"
    "sync"
)

func f1() {
    wg := sync.WaitGroup{}
    wg.Add(3)

    s := []string{"a", "b", "c"}
    for _, i := range s {
        go func() {
            fmt.Printf("%sn", i) // <--- 打印的都是c,也就是打印了3个c
            wg.Done()
        }()
    }

    wg.Wait()
}

func f2() {
    wg := sync.WaitGroup{}
    wg.Add(3)

    s := []string{"a", "b", "c"}
    for _, i := range s {
        go func(t string) {
            fmt.Printf("%sn", t) // <--- a, b, c
            wg.Done()
        }(i)
    }

    wg.Wait()
}

func f3() {
    wg := sync.WaitGroup{}

    i := 0

    for {
        i++
        wg.Add(1)
        go func() {
            fmt.Printf("%sn", i) // <--- 连续打印几个相同的数字,然后跳跃继续
            wg.Done()
        }()
    }

    wg.Wait()
}