Go 团队隆重宣布 Go 1.23 版本正式发布!距离上个版本 Go 1.22 发布已经过去了六个月,这次更新带来了许多令人兴奋的新功能和改进。本文将深入探讨 Go 1.23 的主要变化,包括语言变化、工具链更新、标准库增强以及对不同平台的支持。
语言变化:迭代函数和泛型别名
Go 1.23 在语言层面上的最大亮点是将“range-over-func”实验性功能正式纳入语言规范。现在,for-range
循环中的 range
子句可以接受以下类型的迭代函数作为范围表达式:
func(func() bool)
func(func(K) bool)
func(func(K, V) bool)
迭代函数的调用将为 for-range
循环生成迭代值。更多详细信息请参考 iter
包文档和语言规范。
此外,Go 1.23 还引入了对泛型类型别名的预览支持。通过设置环境变量 GOEXPERIMENT=aliastypeparams
,您可以在包内启用此功能。但需要注意的是,跨包边界使用泛型别名类型尚不支持。
Telemetry:帮助 Go 团队更好地了解 Go 的使用情况
从 Go 1.23 开始,Go 工具链可以收集使用情况和错误统计信息,以帮助 Go 团队了解 Go 工具链的使用方式及其运行状况。我们将这些统计信息称为 Go Telemetry。
Go Telemetry 是一个可选系统,由 go telemetry
命令控制。默认情况下,工具链程序将统计信息收集到计数器文件中,这些文件可以在本地进行检查,但不会被其他方式使用(go telemetry local
)。
为了帮助我们保持 Go 良好运行并了解 Go 的使用情况,请考虑通过运行 go telemetry on
选择加入 Go Telemetry。在这种模式下,匿名计数器报告将每周上传到 telemetry.go.dev,并在那里汇总成图表,供任何想要分析数据的 Go 贡献者或用户下载。有关 Go Telemetry 系统的更多详细信息,请参阅“Go Telemetry”。
Go 命令:改进模块管理和环境变量设置
- 设置
GOROOT_FINAL
环境变量不再有任何效果。建议将go
命令安装到$GOROOT/bin/go
以外的路径时,应该安装一个符号链接,而不是重新定位或复制go
二进制文件。 - 新增
go env -changed
标志,该标志将只打印那些有效值与其默认值不同的设置。 - 新增
go mod tidy -diff
标志,该标志将不会修改文件,而是以统一的差异格式打印必要的更改。如果需要更新,它将以非零代码退出。 go list -m -json
命令现在包含新的Sum
和GoModSum
字段。这类似于go mod download -json
命令的现有行为。- 在
go.mod
和go.work
中新增godebug
指令,用于声明要应用于正在使用的模块或工作区的 GODEBUG 设置。
其他重要更新
- Vet:
go vet
子命令现在包含stdversion
分析器,它会标记对那些对于引用文件中生效的 Go 版本来说太新的符号的引用。 - Cgo:
cmd/cgo
支持新的-ldflags
标志,用于将标志传递给 C 链接器。go
命令会自动使用它,以避免在CGO_LDFLAGS
非常大的情况下出现“参数列表过长”的错误。 - Trace:
trace
工具现在可以更好地容忍部分损坏的跟踪,方法是尝试恢复它可以恢复的跟踪数据。当查看在程序崩溃期间收集的跟踪时,此功能特别有用,因为在大多数情况下,现在可以恢复导致崩溃的跟踪数据。 - Runtime: 在未处理的 panic 或其他致命错误之后,运行时打印的回溯现在将错误消息的第二行和后续行(例如,panic 的参数)缩进一个制表符,以便可以将其与第一个 goroutine 的堆栈跟踪明确区分开来。
- Compiler: 使用配置文件引导优化 (PGO) 进行构建时的构建时间开销已显着减少。以前,大型构建可能会看到启用 PGO 后构建时间增加 100% 以上。在 Go 1.23 中,开销应该在个位数百分比。
- Linker: 链接器现在禁止使用
//go:linkname
指令来引用标准库(包括运行时)中未在其定义上标记//go:linkname
的内部符号。类似地,链接器也禁止从汇编代码中引用此类符号。为了向后兼容,仍然支持在大型开源代码库中发现的//go:linkname
的现有用法。任何对标准库内部符号的新引用都将被禁止。 - 标准库: Go 1.23 对标准库进行了多项改进,包括:
- 对
time.Timer
和time.Ticker
的实现进行了两项重大更改:未引用的计时器和周期性计时器现在可以立即进行垃圾回收,即使它们的Stop
方法尚未被调用;与计时器或周期性计时器关联的计时器通道现在是无缓冲的,容量为 0。 - 新增
unique
包,提供用于规范化值(如“interning”或“hash-consing”)的工具。 - 新增
iter
包,提供用于处理用户定义迭代器的基本定义。 - 新增
structs
包,提供用于修改包含结构类型属性(如内存布局)的结构字段的类型。 - 对其他标准库包进行了多项小的更改和改进。
- 对
平台支持
- Darwin: Go 1.23 要求 macOS 11 Big Sur 或更高版本;已停止支持以前的版本。
- Linux: Go 1.23 是最后一个需要 Linux 内核版本 2.6.32 或更高版本的版本。Go 1.24 将需要 Linux 内核版本 3.17 或更高版本,但运行 3.10 或更高版本且已修补内核以支持
getrandom
系统调用的系统除外。 - OpenBSD: Go 1.23 增加了对 64 位 RISC-V (
GOOS=openbsd
,GOARCH=riscv64
) 上 OpenBSD 的实验性支持。 - ARM64: Go 1.23 引入了一个新的
GOARM64
环境变量,用于在编译时指定 ARM64 架构的最低目标版本。允许的值为v8.{0-9}
和v9.{0-5}
。 - RISC-V: Go 1.23 引入了一个新的
GORISCV64
环境变量,用于选择要为其编译的 RISC-V 用户模式应用程序配置文件。允许的值为rva20u64
和rva22u64
。 - Wasm:
GOROOT/misc/wasm
中的go_wasip1_wasm_exec
脚本已放弃对wasmtime
< 14.0.0 版本的支持。
总结
Go 1.23 版本带来了许多令人兴奋的新功能和改进,包括语言变化、工具链更新、标准库增强以及对不同平台的支持。这些更新将使 Go 语言更加强大、高效和易于使用。我们鼓励所有 Go 用户升级到最新版本,以体验这些新功能和改进。