当前位置: 首页 > news >正文

Go闭包【2】 1.22 对 for 循环里闭包陷阱的那个“史诗级更新”

这个更新非常重要,因为它直接终结了 Go 语言过去十年里最常见的 Bug 之一。

在 Go 1.22 之前,我们常说“不要在闭包里直接引用循环变量”,但现在,这个规则变了。

1. 过去的“坑”(Go 1.21 及更早)

在旧版本里,for循环中的变量i是地址复用的。每一轮循环,i都是同一个变量,只是值在变。

func main() { done := make(chan bool) values := []string{"a", "b", "c"} for _, v := range values { go func() { fmt.Println(v) // 闭包引用了同一个变量 v 的地址 done <- true }() } // ... 等待输出 }
  • 旧版本结果:大概率输出c, c, c。因为协程启动慢,等它们运行时,变量v已经变成最后那个 "c" 了。
  • 当时的解法:必须通过传参或者在循环内定义同名局部变量v := v

2. Go 1.22 的“史诗级”变化

从 Go 1.22 开始,官方修改了语义:在for循环中,每一轮迭代都会创建一个新的变量实例。

  • 现在的代码(就是上面那段):直接输出a, b, c(顺序随机)。
  • 底层原理:编译器在每一轮循环里都为你自动做了一次变量隔离。每一轮的v都是独立的,闭包捕获的是那个瞬间的“专属”变量。

3. 为什么说这比较重要?

  1. 心智负担降低:你再也不用为了防范“闭包陷阱”到处写v := v这种看起来像废话的代码了。
  2. 安全性提升:这是 Go 团队为了解决新手甚至老手都常犯的错误,罕见地打破了“保持旧逻辑不变”的传统。
  3. 性能几乎无损:编译器优化得非常好,这种变量分配对绝大多数程序来说没有明显的性能开销。

⚠️ 一个小提醒

这个特性生效的前提是:你的go.mod文件里的版本号必须声明为go 1.22或更高。如果写的是1.21,编译器还是会按旧的那套“有坑”的逻辑来执行。

package main import ( "fmt" "sync" "time" ) func main() { values := []string{"a", "b", "c"} var wg sync.WaitGroup fmt.Println("--- 开始执行 ---") for _, v := range values { wg.Add(1) go func() { defer wg.Done() // 在 Go 1.22 之前,这里的 v 共享同一个地址,最后打印的通常都是最后一个元素 // 在 Go 1.22 之后,这里的 v 每轮都是新变量,能正确打印 a, b, c fmt.Println("当前值:", v) }() } wg.Wait() fmt.Println("--- 执行结束 ---") }

旧版的标准写法

for _, v := range values { wg.Add(1) go func(val string) { defer wg.Done() fmt.Println(val) }(v) }



http://www.jsqmd.com/news/863488/

相关文章:

  • HoRain云--AI 底层架构
  • QQ音乐加密文件终极转换指南:3步将.qmc文件转为MP3/FLAC
  • 达梦数据库-堆栈看问题-01-asmapi_asm_extent_load
  • 如何在Windows上实现专业级游戏控制器模拟:ViGEmBus驱动深度解析
  • DS4Windows终极指南:如何在Windows上完美使用PS4/PS5手柄玩所有游戏
  • Warcraft Helper:现代Windows环境下魔兽争霸3兼容性技术解决方案深度解析
  • TranslucentTB:Windows任务栏透明化终极指南与5大创意应用场景
  • 你的 BroadcastReceiver 为何在后台装死?—— Android 8.0+ 隐式广播限制与动态注册完全指南
  • 苏州购宠避坑指南|5 家靠谱实体门店 - 资讯速览
  • 2026年5月论文降 AI 率工具终极推荐:超过一半学生的选择,早标网为何降AI效果好? - 全维度降AI
  • 10.Python 迭代器、生成器与装饰器 深度解析
  • 3分钟快速上手SketchUp STL插件:终极3D打印模型转换完整指南
  • [MAF的Agent管道详解-04]如何让LLM按照要求的结构输出数据?
  • 浏览器资源嗅探革命:猫抓扩展如何重新定义在线媒体捕获体验
  • 如何快速安装BetterNCM:终极网易云音乐插件管理指南
  • 深度解析Unity游戏实时翻译插件:XUnity.AutoTranslator的5大实战应用场景与架构设计
  • 大学买不到GPU怪我?黄仁勋斯坦福现场火力全开:是你们体制的错!
  • Sub2API + CCSwitch 实现 Codex 反向代理:多账号流量分发实战(解决codex手机号验证)可以润色吗
  • 【紧急更新】Midjourney v6.1金属纹理算法变更预警:3个必须重训的材质参数阈值,错过将导致PBR贴图链断裂
  • 武安市建龙废钢基地物资:峰峰矿专业的废钢回收公司推荐几家 - LYL仔仔
  • 2026年国内矿粉球团粘合剂头部厂家实力排行 - 奔跑123
  • 3步彻底解决Windows右键菜单卡顿:ContextMenuManager终极优化指南
  • 抖音无水印批量下载终极指南:douyin-downloader免费神器
  • 5分钟搭建个人游戏云:Sunshine跨平台串流服务器完全指南
  • 2026年全球优质筋膜枪选购指南:轻松找到你的专属按摩神器 - 博客万
  • G-Helper:华硕笔记本的轻量级性能管家,让你的电脑重获新生
  • N_m3u8DL-CLI-SimpleG:让M3U8视频下载变得如此简单的终极图形界面工具
  • 2026论文降AI率工具谁是性价比之王?早标网最低1.0元/千字性价比拉满 - 全维度降AI
  • MelonLoader终极指南:解锁Unity游戏无限可能的5个核心步骤
  • 2026年软考知识点—计算机等级考试—软件设计师考前备忘录—东方仙盟