Go 1.27 发行说明
摘要
Go 1.27 发布引入了泛型方法以及其他语言和工具链更新,同时保持与之前版本的兼容性。
<p>Go 1.27 交互式导览 <a href="https://victoriametrics.com/blog/go-1-27" rel="ugc">https://victoriametrics.com/blog/go-1-27</a></p>
<p><a href="https://lobste.rs/s/q0wkpe/go_1_27_release_notes">评论</a></p>
查看缓存全文
缓存时间: 2026/08/19 20:34
# Go 1.27 发布说明 - Go 编程语言
来源:https://go.dev/doc/go1.27
## Go 1.27 简介
最新的 Go 发布版本,1.27,将于 2026 年 8 月 (https://go.dev/doc/devel/release#go1.27.0) 发布,距离 Go 1.26 (https://go.dev/doc/go1.26) 发布已有六个月。其大部分更改集中在工具链、运行时和标准库的实现中。一如既往,本次发布遵循了 Go 1 兼容性承诺 (https://go.dev/doc/go1compat)。我们预计几乎所有 Go 程序都能继续编译和运行。
## 语言变更
Go 1.27 现在支持泛型方法 (https://go.dev/issue/77273):方法声明 (https://go.dev/ref/spec#Method_declarations) 可以声明自己的类型参数 (https://go.dev/ref/spec#Type_parameter_declarations)。这项备受期待的更改允许在特定数据类型的命名空间内添加泛型函数,而以前则需要将此类函数声明在整个包范围内。例如,`math/rand/v2` 现在声明了一个泛型方法,签名为 `(*Rand) N[Int intType](Int) Int`,而之前只有一个泛型函数 `N[Int intType](Int) Int` (详情见下文 (https://go.dev/doc/go1.27#rand))。注意,接口 (https://go.dev/ref/spec#Interface_types) 的方法不能声明类型参数,接口方法也不能由泛型方法实现。
结构体字面量 (https://go.dev/ref/spec#Composite_literals) 中的键现在可以是该结构体类型的有效字段选择器 (https://go.dev/issue/9859),而不仅仅是结构体的(顶层)字段名。
函数类型推断已推广 (https://go.dev/issue/77245),适用于泛型函数被赋值 (https://go.dev/ref/spec#Assignability) 给匹配函数类型的变量(或转换为该类型)的所有上下文。
现在 `compile`、`link`、`asm`、`cgo`、`cover` 和 `pack` 工具支持响应文件(`@file`)。响应文件包含以空白符分隔的参数,支持单引号和双引号字符串、转义序列和反斜杠-换行符续行。该格式与 GCC 的响应文件实现兼容,以确保与现有构建系统互操作。
### go 命令
`go` 命令不再支持 `bzr` 版本控制系统。它将无法直接获取托管在 `bzr` 服务器上的模块。
#### `GODEBUG`
从 Go 1.27 开始,`go` 命令现在会识别 `go.mod` 文件(`godebug` 条目)和 `.go` 源文件(`//go:debug` 注释)中设置的、其支持已被移除(例如 `asynctimerchan`,见下文 (https://go.dev/doc/go1.27#runtime))的 `GODEBUG` 设置。如果这些设置被设置为在该设置被移除前确定的最终默认值,则接受它们。如果设置为旧值,`go` 命令将失败。此更改符合 Go 1 兼容性保证 (https://go.dev/doc/go1compat) 的精神,并允许现有的设置受支持 `GODEBUG` 的程序继续构建和运行,无需修改,即使相应的设置支持已被移除。
#### `go test`
`go test` 现在默认调用 `stdversion` vet 检查。此检查会报告在引用文件中(由 `go.mod` 中的 `go` 指令和文件上的构建标签确定)Go 生效版本所支持范围之外的标准库符号的使用情况。
`go test -json` 现在使用一个可选的新字段 `"OutputType"` 来注解 `"Action":"output"` 行,该字段指定输出类型。目前,可能的值包括 "error"、"error-continue" 和 "frame"。详情请参阅 cmd/test2json 帮助 (https://go.dev/cmd/test2json#hdr-Output_Format)。
#### `go doc`
`go doc` 命令现在支持 `package@version` 语法,例如 `go doc example.com/[email protected]`。
`go doc` 命令现在接受 `-ex` 命令行选项,以列出给定包或符号的可执行示例。当在命令行上传递示例名称(如 `go doc bytes.ExampleBuffer`)时,`go doc` 现在会连同注释一起打印示例源代码。
#### `go fix`
`go fix` 命令包含几个新的现代化工具(`atomictypes`、`embedlit`、`slicesbackward` 和 `unsafefuncs`)。
由于风格考虑,已移除现有的 `fmtappendf` 分析器。
现有的 `waitgroup` 分析器已重命名为 `waitgroupgo`,以避免歧义。
#### `go mod tidy`
对于在 `go.mod` 文件中指定 `go 1.27` 或更高版本的模块,`go mod tidy` 现在会自动合并重复的 require 块。这确保文件保持干净、标准的结构,最多包含两个 require 块:一个用于直接依赖,一个用于间接依赖。
在此合并过程中,附加在依赖上的现有注释块将被保留。如果一个注释块与混合指令集(包含直接和间接依赖)相关联,则该注释块将被合并并附加到新的直接依赖块。
以前,如果 `go.mod` 文件积累了多个不相交的 require 块(通常是由于手动编辑、未解决的 Git 合并冲突或遗留升级造成的),`go mod tidy` 会保留额外的块或无意中创建新的块。该工具现在严格强制执行双块布局,将不同的需求合并到各自的块中,并自动清理模块文件的结构。
### Trace
`go tool trace` 的 `-http` 命令行选项现在当仅传递端口(例如 `-http=:6060`)时,会将监听地址限制为 localhost。此更改使 `go tool trace` 与 `go tool pprof` 的 `-http` 标志行为一致。要监听所有地址,请显式包含指定地址(例如 `-http=0.0.0.0:6060`)。
## 运行时
配置为 Go 1.27 或更高版本的模块的堆栈跟踪现在将在标题行中包含 `runtime/pprof` (https://pkg.go.dev/runtime/pprof) goroutine 标签。可以使用 `tracebacklabels=0` `GODEBUG` 设置(在 Go 1.26 (https://go.dev/doc/godebug#go-126) 中添加)禁用此行为。如果 goroutine 标签可能包含不应在堆栈跟踪中公开的敏感信息,则此退出选项预计会无限期保留。
`asynctimerchan` `GODEBUG` 设置(在 Go 1.23 (https://go.dev/doc/godebug#go-123) 中添加)已被永久移除。由 time 包 (https://pkg.go.dev/time) 创建的通道现在始终是无缓冲的(同步的),无论 `GODEBUG` 设置如何。
### 更快的内存分配
编译器现在生成对特定大小内存分配例程的调用,将一些小型(< 80 字节)内存分配的成本降低了高达 30%。改进因工作负载而异,但在实际内存密集型程序中,预计总体改进约为 1%。这导致二进制文件大小增加约 60 KB(与工作负载无关)。如果您注意到任何性能回退,请提交问题 (https://go.dev/issue/new)。您可以在构建时设置 `GOEXPERIMENT=nosizespecializedmalloc` 来禁用它。此退出选项预计将在 Go 1.28 中移除。
### Goroutine 泄漏 Profile
一种报告泄漏 goroutine 的新 profile 类型,之前在 Go 1.26 (https://go.dev/doc/go1.26#goroutineleak-profiles) 中作为实验功能提供,现在正式可用。新的 profile 类型名为 `goroutineleak`,在 `runtime/pprof` (https://go.dev/pkg/runtime/pprof) 包中支持。它也可作为 `net/http/pprof` (https://go.dev/pkg/net/http/pprof) 端点 `/debug/pprof/goroutineleak` 使用。
*泄漏*的 goroutine 是指被阻塞在某个并发原语(通道、`sync.Mutex` (https://go.dev/pkg/sync#Mutex)、`sync.Cond` (https://go.dev/pkg/sync#Cond) 等)上,并且永远不可能解除阻塞的 goroutine。运行时使用垃圾收集器来检测泄漏的 goroutine:如果一个 goroutine G 被阻塞在并发原语 P 上,而 P 从任何可运行的 goroutine 或任何这些 goroutine *可能*解除其阻塞的 goroutine 都不可达,那么 P 就无法解除阻塞,因此 goroutine G 永远无法唤醒。虽然无法检测所有情况下永久阻塞的 goroutine,但这种方法能检测到大量此类泄漏。
因为这种技术建立在可达性之上,运行时可能无法检测到由于阻塞在通过全局变量或可运行 goroutine 的局部变量可达的并发原语而导致的泄漏。
参见 Go 1.26 发布说明 (https://go.dev/doc/go1.26#goroutineleak-profiles) 中的示例。
特别感谢 Uber 的 Vlad Saioc 贡献了这项工作。
`goroutineleak` profile 的 `GOEXPERIMENT` 设置现已删除。
## 编译器
编译器现在解析 `//line` 或 `/*line*/` 指令中的相对文件名时,是相对于包含该指令的文件的目录进行的,这与 `go/scanner` (https://go.dev/pkg/go/scanner) 的行为一致。绝对文件名不受影响。参见 #70478 (https://go.dev/issue/70478)。
编译器现在为函数字面量(闭包)生成更简单的名称。以前,当包含的函数被内联时,函数字面量的名称可能会变得很长。现在编译器无论是否内联,都为函数字面量选择相同的名称。当其包含的函数被内联时,它还可以将同一函数字面量的多个实例合并,以在编译后的二进制文件中共享相同的代码。此更改不影响 Go 代码的功能。检查符号名称的测试可能需要更新,尽管建议不要依赖函数字面量的名称。对于错误 (https://go.dev/pkg/reflect#Value.Pointer) 比较函数代码指针的程序,此问题在 Go 1.27 中可能会更频繁地暴露,因为在更多情况下,具有不同捕获闭包数据的函数字面量可能具有相等的代码指针。
## 链接器
当目标平台为 macOS 时,链接器现在接受 `-macos` 和 `-macsdk` 命令行选项,用于在 `LC_BUILD_VERSION` 加载命令中指定操作系统和 SDK 版本。默认情况下,它选择最旧的支持 macOS 版本(目前为 13.0.0 (https://go.dev/doc/go1.27#darwin))和最近的 SDK 版本(目前为 26.2.0)。
## 标准库
### 新的 encoding/json/v2 和 encoding/json/jsontext 包
现在提供两个新包:
- `encoding/json/v2` (https://go.dev/pkg/encoding/json/v2) 包是 `encoding/json` (https://go.dev/pkg/encoding/json) 的主要修订版。它提供 `Marshal` (https://go.dev/pkg/encoding/json/v2#Marshal)、`MarshalWrite` (https://go.dev/pkg/encoding/json/v2#MarshalWrite)、`MarshalEncode` (https://go.dev/pkg/encoding/json/v2#MarshalEncode)、`Unmarshal` (https://go.dev/pkg/encoding/json/v2#Unmarshal)、`UnmarshalRead` (https://go.dev/pkg/encoding/json/v2#UnmarshalRead) 和 `UnmarshalDecode` (https://go.dev/pkg/encoding/json/v2#UnmarshalDecode),所有这些函数都接受可变的 `Options` (https://go.dev/pkg/encoding/json/v2#Options) 参数来配置序列化和反序列化行为。
- `encoding/json/jsontext` (https://go.dev/pkg/encoding/json/jsontext) 包提供较低级别的 JSON 语法处理。`Encoder` (https://go.dev/pkg/encoding/json/jsontext#Encoder) 和 `Decoder` (https://go.dev/pkg/encoding/json/jsontext#Decoder) 类型将 JSON 视为 `Token` (https://go.dev/pkg/encoding/json/jsontext#Token) 和 `Value` (https://go.dev/pkg/encoding/json/jsontext#Value) 序列进行操作,并维护一个状态机以确保生成或消费的序列是有效的 JSON 文本。
v2 包选择了比 v1 更严格、更可互操作的默认值:它拒绝 JSON 字符串中无效的 UTF-8 并拒绝 JSON 对象中的重复名称。请参阅 v1 `encoding/json` (https://go.dev/pkg/encoding/json#hdr-Migrating_to_v2) 包文档了解完整的行为差异集以及可用于调整它们的选项。
`encoding/json` (https://go.dev/pkg/encoding/json) 包现在由 v2 实现提供支持。序列化和反序列化行为得以保留,但错误消息的确切文本可能会有所不同。该包还获得了一些新的 `Options` (https://go.dev/pkg/encoding/json#Options),可以配置 v2 以 v1 语义运行,从而避免需要完全迁移到新 API。v1 API 将继续得到支持,用户无需迁移。
序列化性能与之前的实现大致相当,而反序列化性能显著提升。
遇到与新实现兼容性问题的用户可以通过在构建时设置 `GOEXPERIMENT=nojsonv2` 来禁用它,恢复原始的 v1 实现。此退出选项预计将在未来版本中移除。
参见提案问题 (https://go.dev/issue/71497) 了解更多背景信息和详细信息。如果您需要禁用新实现,请提交问题 (https://go.dev/issue/new)。
### 新的 crypto/mldsa 包
新的 `crypto/mldsa` (https://go.dev/pkg/crypto/mldsa) 包实现了 FIPS 204 中规定的后量子 ML-DSA 签名方案。
`crypto/x509` (https://go.dev/pkg/crypto/x509) 现在支持 ML-DSA 私钥、公钥和签名。
`crypto/tls` (https://go.dev/pkg/crypto/tls) 现在支持 TLS 1.3 中的 ML-DSA 签名,包含新的 `MLDSA44` (https://go.dev/pkg/crypto/tls#MLDSA44)、`MLDSA65` (https://go.dev/pkg/crypto/tls#MLDSA65) 和 `MLDSA87` (https://go.dev/pkg/crypto/tls#MLDSA87) `SignatureScheme` (https://go.dev/pkg/crypto/tls#SignatureScheme) 值。
### 新的 uuid 包
新的 `uuid` (https://go.dev/pkg/uuid) 包用于生成和解析 UUID。
### 新的实验性 simd 包
Go 1.27 引入了一个新的实验性 `simd` (https://go.dev/pkg/simd) 包,提供可移植且与向量大小无关的 SIMD 支持。如果硬件指令可用,它将使用这些指令。通过在构建时设置环境变量 `GOEXPERIMENT=simd` 来启用此包。
`simd` 包在所有架构上可用,并提供未指定大小的向量类型,例如 `Int8s` (https://go.dev/pkg/simd#Int8s) 和 `Float32s` (https://go.dev/pkg/simd#Float32s)。它支持 `simd/archsimd` (https://go.dev/pkg/simd/archsimd) 包中硬件支持或在不同架构和向量宽度上易于模拟的操作的“可伸缩”子集。
参见提案问题 (https://go.dev/issue/78902) 了解更多详情。
### 实验性 simd/archsimd 包
Go 1.27 继续对 `simd/archsimd` (https://go.dev/pkg/simd/archsimd/) 包中的 SIMD 操作提供实验性支持,该支持始于 Go 1.26 (https://go.dev/doc/go1.26#simd)。此版本修订了 amd64 API,并添加了对 arm64 “Neon” 128 位 SIMD 和 WebAssembly 128 位 SIMD 的支持。通过在构建时设置环境变量 `GOEXPERIMENT=simd` 来启用 `simd/archsimd` 包。
此包提供对特定架构 SIMD 操作的访问。它在 wasm、arm64 和 amd64 上支持 128 位向量类型,在某些 amd64 处理器上支持 256 位和 512 位向量类型。该 API 尚未被认为是稳定的。
参见包文档 (https://go.dev/pkg/simd/archsimd) 和提案问题 (https://go.dev/issue/73787) 了解更多详情。
我们打算在未来版本中提供对其他架构的支持,但该 API 是有意设计为特定于架构的,因此不可移植。
### 标准库的次要更改
#### `bytes` (https://go.dev/pkg/bytes/)
新的 `CutLast` (https://go.dev/pkg/bytes#CutLast) 函数围绕分隔符的最后一次出现切割 `[]byte`。它可以替代并简化 `LastIndex` (https://go.dev/pkg/bytes#LastIndex) 的一些常见用法。
#### `compress/flate` (https://go.dev/pkg/compress/flate/)
Go 1.27 中压缩速度得到提升。由于编码器实现更改,`Writer` (https://go.dev/pkg/compress/flate#Writer) 产生的具体编码输出可能与 Go 1.26 不同。由于
相似文章
Go 1.27 发布 - Go 编程语言
Go 1.27 已发布,包含重大增强,如泛型方法、性能改进以及新标准库特性,例如 encoding/json/v2 和后量子密码学支持。
Go 1.27 中的泛型方法
Go 1.27 引入了泛型方法,允许方法在不修改接收结构体的情况下定义自己的类型参数,从而解决了 Go 1.18 中的局限性。但由于运行时约束,接口仍被排除在外。
Go 1.27 交互式导览
Go 1.27 新功能的实践性交互式导览,重点介绍泛型方法、结构体字面量字段选择器等,并提供基于官方发布说明的可运行示例。
Java 27:有哪些新功能?
Java 27 为编程语言引入了新功能和改进。
JetBrains Go现代编码规范指南
JetBrains发布了一个GitHub仓库,其中包含编写现代Go代码的代码代理指南,涵盖了Go 1.27的所有功能,并与Junie和Claude Code等工具集成。