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)

}

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

相关推荐
运维行者_3 分钟前
使用Applications Manager监控的关键MongoDB指标
服务器·开发语言·网络·数据库·mongodb·机器学习·云计算
明月_清风11 分钟前
Base64:用 33% 的体积膨胀,买一张在文本世界通行的门票
后端
解决问题no解决代码问题12 分钟前
设计模式分类介绍
java·开发语言·设计模式
得物技术14 分钟前
HorizonVault 技术深潜:如何在 HDD 上做出 100GB/s+ 级大吞吐分布式存储|得物技术
大数据·后端·kafka
sugar__salt15 分钟前
从Python列表切片到LLM接口实战:零基础AI编程落地教程
开发语言·python·ai·prompt·transformer·ai编程
码不停蹄的玄黓18 分钟前
SpringBoot 自动装配原理
java·spring boot·后端
z落落19 分钟前
C# 数组属性和方法(Clear / Copy / IndexOf / LastIndexOf)
开发语言·javascript·c#
XovH20 分钟前
Docker 从 0 到 1 再到 Kubernetes 实战:深入理解 Docker 镜像和分层结构
后端
白露与泡影22 分钟前
Java虚拟线程实战:从线程池痛点到性能优化全流程
java·开发语言·性能优化
IT空门:门主25 分钟前
Java 单例模式详解:7 种实现方式 + volatile 原理 + 反射与序列化问题
java·开发语言·单例模式