Go 中 for循环内使用协程的变量值脏读问题

问题代码

每个学Go的都要踩的坑。

如下代码的输出, 我们在 for 循环中,使用了协程(go runtime)。

go 复制代码
package main

import (
	"fmt"
	"time"
)

func main() {

	values := []string{"a", "b", "c"}
	for _, v := range values {
		go func() {
			fmt.Println(v)
		}()
	}

	time.Sleep(3 * time.Second)

}

结果是

不是预想的 a,b, c 乱序

原因:因为这里的v 是一个指针变量, 每次循环都会重新赋值, 再执行每次的fmt.Println(v) 之前,v 的值就被改了, 这里被坑惨了。。。

解决手段

重新声明一个变量,传给协程。 代码修改后

go 复制代码
package main

import (
   "fmt"
   "time"
)

func main() {

   values := []string{"a", "b", "c"}
   for _, v := range values {
   	go func(v string) {
   		fmt.Println(v)
   	}(v)
   }

   time.Sleep(3 * time.Second)

}

输出结果:
符合我们的预期。

相关推荐
会编程的土豆几秒前
MySQL 窗口函数详解
数据库·后端·mysql
其实防守也摸鱼几秒前
软件安全与漏洞--实验 软件安全设计
开发语言·网络·python·安全·软件安全·实验·软件安全设计
asdfg12589631 分钟前
无用空数组的用法:numberList.toArray(new Integer[0])
java·开发语言
likerhood5 分钟前
认识 JVM:Java 程序背后的那台“隐形计算机”
java·开发语言·jvm
wangchunting5 分钟前
Java9功能更新说明
java·开发语言
~|Bernard|5 分钟前
三,go语言中channel的底层原理
开发语言·后端·golang
likerhood8 分钟前
Java 反射与注解的详细讲解
java·开发语言·数据库
asdfg12589639 分钟前
从Java的设计模式看接口和实现---List与ArrayList
java·开发语言·设计模式·面向对象·面向接口
云深麋鹿13 分钟前
C++ | map&set的使用
开发语言·c++
allnlei14 分钟前
gRPC C++ Callback API(Reactor 模式)介绍
开发语言·c++