21CTO导读:大多数版本说明文章读起来都像变更日志,而这份版本说明读起来却像是一连串的有趣的道歉声明。以下列出了变更内容、变更原因以及可以忽略的内容。
我阅读 Go 1.26 发行说明的方式与阅读大多数开源软件发行说明的方式相同:快速浏览主要功能,忽略其余部分,然后再回到我的源代码中。
然后,我又再次读了一遍。
我第二次注意到,1.26 版本几乎没有什么引人注目的改动。没有会在 Hacker News 上爆红的新语言特性,也没有“Go 获得异步功能”这样的重大事件。相反,它悄然修复了多年来一直困扰 Go 开发者的问题,并带来了一项真正重要的运行时变更,几乎所有生产服务都将从中受益。
让我带你了解一下实际发生了哪些变化,你应该关注哪些方面,以及你可以忽略哪些方面。
如果这篇文章你只能读一部分,那就请读这一部分。
Go 1.25 将 GreenTea (绿茶)垃圾回收器作为可选实验方案推出。Go 1.26 则将其设为默认方案。Go 团队报告称道,在实际程序中, GC 开销降低了 10% 到 40%,如果运行在 Intel Ice Lake 或 AMD Zen 4 或更新的处理器上,还能在此基础上再降低约 10%(因为新的回收器使用向量指令来扫描小对象)。
我需要谨慎对待这个数字,因为“10%–40%”这个范围本身意义不大,需要结合上下文才能理解。这里需要说明的是:这是垃圾回收 (GC) 时间的减少,而不是总运行时间的减少。如果你的服务 20% 的 CPU 都花在了 GC 上,那么你只需要将 CPU 使用率降低到 12% 到 18% 之间。这不需要重写代码,简直是轻而易举。
GOEXPERIMENT=greenteagc你无需进行任何操作即可获得此功能。升级到 1.26 版本后,您的服务会自动获得此功能。如果你已经在 1.25 版本中运行此功能,则可以安全移除该标志。
使用新表达式new()
这个虽然是件小事,但也是多年来我一直渴望的改变。
在 Go 1.26 中,内置new函数接受一个表达式作为其操作数:
func personJSON(name string, born time.Time)([]byte,error) {return json.Marshal(Person{Name: name,Age:new(yearsSince(born)),// ← 这里是new})}
在 1.26 版本之前,你需要分两步编写这段代码:age := yearsSince(born)returnjson.Marshal(Person{Name: name,Age: &age,})
虽然应用场景比较窄,但确实存在实用点:任何指向可选值的指针字段(JSON、protobuf、gRPC),现在都可以直接内联填充。这种变化在基准测试中可能不明显,但在你做过的每一次代码审查中都会体现出来。
type Adder[A Adder[A]]interface {Add(A) A}
这是库作者非常喜欢的特性,而应用程序开发者则无需再编写任何代码。如果你正在构建数学库或集合框架,这将带来更简洁的抽象。如果你正在构建 Web 服务,则可以跳过这一部分。
go fix重生了这是我最期待的改变,但却是没人谈论的改变。
go fix它已完全重写。现在,它是 Go 语言现代化工具的家园——数十个自动化修复工具,可将你的代码更新为使用现代的惯用法和 API。它使用与 Go 相同的分析框架go vet,这意味着你已经信任的诊断工具现在可以建议并应用修复。
最强大的功能是源代码级内联。如果您维护一个库,并希望用户迁移到新的 API,您可以编写一个//go:fix inline指令,系统go fix会自动重写他们的代码。
实际上,这意味着:
go fix ./...不再需要使用新的惯用法。如果你曾经维护过庞大的 Go 代码库,并且害怕收到“升级 Go 版本”的 PR,那么这篇文章就是为你准备的。
Go 1.26 版本中还包含了其他三项运行时变更:
更快的 cgo 调用。如果你有一个 Go 服务需要调用 C 库(例如数据库驱动程序、图像处理程序或任何封装了 C API 的库),那么 cgo 的开销现在大大降低了。Go 团队尚未公布具体数值,但此次改进旨在降低每次调用的开销,尤其是在高负载路径中。
堆基地址随机化。这是一项安全加固措施。堆基地址现在已随机化,这使得某些内存损坏攻击更难得逞。您在代码中不会注意到这一点,但您的安全团队会在他们的威胁模型中发现它。
实验性 goroutine 泄漏分析。一种新的pprof分析类型,用于检测 goroutine 泄漏。此功能尚处于实验阶段,因此请勿将其用于生产环境调试,但值得在测试套件中尝试。
1.26 发布三个新库。包括如下:
crypto/hpke— 混合公钥加密。如果你曾经需要在不事先进行密钥交换的情况下使用公钥加密数据,那么这就是标准做法。它现在已集成到标准库中,不再是第三方依赖项。
simd/archsimd(实验性)— SIMD 原语。如果您一直想用 Go 编写向量化代码,又不想直接使用汇编语言,那么这就是基础。它目前处于实验阶段,因此 API 会不断变化,但方向很明确:Go 正在认真提升 CPU 级性能。
runtime/secret(实验性)——一个用于管理密钥的软件包,无需将其暴露在堆栈跟踪、崩溃消息或日志中。这种功能早就应该出现了。它目前仍处于实验阶段,但如果按原样发布,将是一项真正的安全改进。
你应该了解的两项变化:
cmd/doc并go tool doc已被删除。请改用go doc等其他方法。相同的标志,相同的行为。如果你有调用该方法的脚本go tool doc,请立即更新它们。
pprof网页界面默认显示火焰图。如果你更喜欢旧版图表视图,它仍然位于“视图”→“图表”下,或者在/ui/graph中
并非版本发布中的每一项变更对每位开发者都至关重要。以下变更可以忽略:
simd/archsimd,runtime/secret)——它们是实验性的,API 将会改变,你现在不应该用它们构建生产系统。go fix ./...先在一个小项目上运行一下。看看现代化工具会给出什么建议。你会惊讶地发现,你的代码中有多少地方还在使用过时的写法。new(expr)下次编写 JSON 序列化函数时可以尝试一下。这只是一个小小的改动,但累积起来会效果显著。Go 1.26 版本不会引发任何会议型的讨论,但它能让你现有的代码运行得更快、升级更轻松、代码库更简洁,而你无需做任何事情。
单凭Green GC就值得升级,go fix重写也值得升级,new(expr)改动也值得升级。随便选一项,升级就值回票价。
看起来,那些看似平平淡淡的发行版本才是最重要的。
go fix文档: https://go.dev/doc/go1.26#go-fixnew(expr)语言规范泄漏分析文档: https://go.dev/doc/go1.26#runtime
本篇文章为 @ 场长 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 微信公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。
请扫描二维码,使用微信支付哦。