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)

}

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

相关推荐
MATLAB代码顾问3 分钟前
Python NumPy数值计算核心指南
开发语言·python·numpy
布朗克1687 分钟前
38 Spring Boot入门——自动配置、核心注解与Starter机制
java·spring boot·后端
只做人间不老仙8 分钟前
C++ grpc 拦截器示例学习
开发语言·c++·学习
踏着七彩祥云的小丑10 分钟前
Go学习第7天:Map集合 + 递归函数 + 类型转换
开发语言·学习·golang·go
程序员老申11 分钟前
外呼突然全挂了,追查 24 分钟后我发现了 etcd 最阴的一颗雷
后端·程序员
何以解忧,唯有..12 分钟前
Go语言变量的声明方式详解
开发语言·后端·golang
长栎13 分钟前
MyBatis 缓存为啥总是失效?装饰器模式套娃的代价
后端
bright_ye14 分钟前
setjmp & longjmp 深度详解 + 代码示例
后端
To_OC14 分钟前
我一直以为 Ajax 是个黑盒,直到我写了这 50 行代码
前端·后端·全栈
她的男孩16 分钟前
AI 自动化编写 SQL 脚本,更要守住 Flyway 版本管理的防线
人工智能·后端