package
0.0.0-20240429050328-3be44a187b12
Repository: https://github.com/robertwang/golang_study.git
Documentation: pkg.go.dev

# README

Go每日一题

今日(2022-12-26) 的题目如下

下面这段代码输出什么?为什么?

func main() {

	var m = [...]int{1, 2, 3}

	for i, v := range m {
		go func() {
			fmt.Println(i, v)
		}()
	}

	time.Sleep(time.Second * 3)
}
🔑 答案解析:

参考答案及解析:

2 3
2 3
2 3

for range 使用短变量声明 (:=) 的形式迭代变量,需要注意的是,变量 i、v 在每次循环体中都会被重用,而不是重新声明。

各个 goroutine 中输出的 i、v 值都是 for range 循环结束后的 i、v 最终值,而不是各个 goroutine 启动时的 i, v值。可以理解为闭包引用,使用的是上下文环境的值。两种可行的 fix 方法:

  • a. 使用函数传递
for i, v := range m {
	go func(i,v int) {
		fmt.Println(i, v)
	}(i,v)
}
  • b. 使用临时变量保留当前值
for i, v := range m {
	i := i           // 这里的 := 会重新声明变量,而不是重用
	v := v
	go func() {
		fmt.Println(i, v)
	}()
}

reference: https://tonybai.com/2015/09/17/7-things-you-may-not-pay-attation-to-in-go/