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

2017/12/13

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

如果循环次数比较少的话,那么函数所引用的外部变量就会变成最后一个值,在函数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("%s\n", 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("%s\n", 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("%s\n", i) // <--- 连续打印几个相同的数字,然后跳跃继续
			wg.Done()
		}()
	}

	wg.Wait()
}