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

Go 1.25正式发布

最新的 Go 版本 1.25 于 2025 年 8 月发布,距离 Go 1.24 间隔六个月。其大部分变化集中在工具链、运行时和库的实现上。与往常一样,该版本保持了 Go 1 的兼容性承诺。我们预计几乎所有 Go 程序都能像以前一样继续编译和运行。

语言变化

Go 1.25 中没有影响 Go 程序的语言变化。不过,在语言规范中,“核心类型” 的概念已被移除,取而代之的是专门的描述文字。更多信息请参见相关博客文章。

工具

Go 命令

go build -asan 选项现在默认在程序退出时进行内存泄漏检测。如果 C 分配的内存未被释放,且未被 C 或 Go 分配的任何其他内存引用,将会报告错误。运行程序时,可通过设置环境变量 ASAN_OPTIONS=detect_leaks=0 禁用这些新的错误报告。

Go 发行版将包含更少的预构建工具二进制文件。核心工具链二进制文件(如编译器和链接器)仍会包含,但 go tool 不会再预构建那些不被构建或测试操作调用的工具,而是会根据需要动态构建和运行它们。

新的 go.modignore 指令可用于指定命令应忽略的目录。这些目录及其子目录中的文件在匹配包模式(如 go all 或 ./...)时会被命令忽略,但仍会包含在模块压缩文件中。

新的 go doc -http 选项会启动一个文档服务器,显示请求对象的文档,并在浏览器窗口中打开该文档。

新的 go version -m -json 选项会打印嵌入在给定 Go 二进制文件中的 runtime/debug.BuildInfo 结构的 JSON 编码。

当使用 <meta name="go-import" content="root-path vcs repo-url subdir"> 语法解析模块路径时,go 命令现在支持将仓库的子目录用作模块根目录,其中 root-path 对应 vcs 版本控制系统中 repo-url 的 subdir

新的 work 包模式匹配工作模块(以前称为主模块)中的所有包:在模块模式下为单个工作模块,在工作区模式下为一组工作区模块。

当 go 命令更新 go.mod 或 go.work 文件中的 go 行时,不再添加指定命令当前版本的工具链行。

Vet

go vet 命令包含新的分析器:

  • waitgroup:报告 sync.WaitGroup.Add 的错误调用位置;
  • hostport:报告使用 fmt.Sprintf("%s:%d", host, port) 构建 net.Dial 地址的情况(这些地址在 IPv6 下无法工作),并建议使用 net.JoinHostPort

运行时

感知容器的 GOMAXPROCS

GOMAXPROCS 的默认行为已更改。在早期 Go 版本中,GOMAXPROCS 默认值为启动时可用的逻辑 CPU 数量(runtime.NumCPU)。Go 1.25 引入了两项变化:

在 Linux 上,运行时会考虑包含该进程的 cgroup 的 CPU 带宽限制(如果有)。如果 CPU 带宽限制低于可用的逻辑 CPU 数量,GOMAXPROCS 默认值会设为较低的限制。在 Kubernetes 等容器运行时系统中,cgroup CPU 带宽限制通常对应 “CPU 限制” 选项。Go 运行时不考虑 “CPU 请求” 选项。

在所有操作系统上,如果可用逻辑 CPU 数量或 cgroup CPU 带宽限制发生变化,运行时会定期更新 GOMAXPROCS

如果通过环境变量或调用 runtime.GOMAXPROCS 手动设置了 GOMAXPROCS,上述两种行为都会自动禁用。也可分别通过 GODEBUG 设置 containermaxprocs=0 和 updatemaxprocs=0 显式禁用它们。

为了支持读取更新的 cgroup 限制,运行时会在进程生命周期内缓存 cgroup 文件的文件描述符。

新的实验性垃圾收集器

现在有一个新的垃圾收集器作为实验特性可用。该垃圾收集器的设计通过更好的局部性和 CPU 可扩展性,提高了标记和扫描小对象的性能。基准测试结果各不相同,但我们预计在重度使用垃圾收集器的实际程序中,垃圾收集开销会减少 10% - 40%。

可在构建时通过设置 GOEXPERIMENT=greenteagc 启用新的垃圾收集器。我们预计其设计会继续演进和改进。为此,我们鼓励 Go 开发者尝试使用并反馈体验。更多设计细节和反馈说明请参见 GitHub issue。

Trace flight recorder¶

长期以来,运行时执行跟踪提供了一种强大但开销较大的方式,用于理解和调试应用程序的底层行为。但由于其体积较大且持续写入执行跟踪的成本较高,通常难以用于调试罕见事件。

新的 runtime/trace.FlightRecorder API 提供了一种轻量级的方式来捕获运行时执行跟踪:它会持续将跟踪记录到内存中的环形缓冲区。当发生重要事件时,程序可调用 FlightRecorder.WriteTo 将最近几秒的跟踪快照写入文件。这种方式通过让应用程序只捕获关键跟踪,生成的跟踪文件小得多。

FlightRecorder 捕获的时间长度和数据量可在 FlightRecorderConfig 中配置。

未处理恐慌输出的变化

当程序因未处理的恐慌(已恢复并再次恐慌)退出时,打印的消息不再重复恐慌值的文本。

以前,一个程序若因 panic("PANIC") 恐慌、恢复恐慌后又用原始值再次恐慌,会打印:

plaintext

panic: PANIC [recovered]panic: PANIC

现在该程序会打印:

plaintext

panic: PANIC [recovered, repanicked]

Linux 上的 VMA 名称

在支持匿名虚拟内存区域(VMA)名称的 Linux 系统(CONFIG_ANON_VMA_NAME)上,Go 运行时会为匿名内存映射添加用途相关的上下文标注。例如,堆内存会标注为 [anon: Go: heap]。可通过 GODEBUG=decoratemappings=0 禁用此功能。

编译器

空指针漏洞

此版本修复了 Go 1.21 中引入的一个编译器漏洞,该漏洞可能错误地延迟空指针检查。如下程序以前能(错误地)成功执行,现在会(正确地)因空指针异常恐慌:

go

package mainimport "os"func main() {f, err := os.Open("nonExistentFile")name := f.Name()if err != nil {return}println(name)
}

该程序存在问题,因为它在检查错误之前使用了 os.Open 的结果。如果 err 非空,f 可能为 nil,此时 f.Name() 应恐慌。但在 Go 1.21 到 1.24 版本中,编译器错误地将空检查延迟到错误检查之后,导致程序违反 Go 规范却能成功执行。在 Go 1.25 中,它将不再成功运行。如果此变化影响了你的代码,解决方法是将非空错误检查放在代码中更早的位置,最好是在生成错误的语句之后。

DWARF5 支持

Go 1.25 中的编译器和链接器现在使用 DWARF 版本 5 生成调试信息。较新的 DWARF 版本减少了 Go 二进制文件中调试信息所需的空间,并缩短了链接时间(尤其是大型 Go 二进制文件)。可在构建时通过设置环境变量 GOEXPERIMENT=nodwarf5 禁用 DWARF 5 生成(此回退选项可能在未来版本中移除)。

更快的切片

编译器现在能在更多情况下在栈上分配切片的底层存储,从而提高性能。此变化可能会放大不正确的 unsafe.Pointer 使用带来的影响(例如 issue 73199)。为了追踪这些问题,可使用 bisect 工具并通过 -compile=variable 标志查找有问题的分配。也可通过 make -gcflags=all=-d=variablehash=n 关闭所有此类新的栈分配。

链接器

链接器现在接受 funcalign=N 命令行选项,用于指定函数入口的对齐方式。默认值取决于平台,本版本中未改变。

标准库

新的 testing/synctest 包

新的 testing/synctest 包为测试并发代码提供支持。

Test 函数在隔离的 “气泡” 中运行测试函数。在气泡内,时间是虚拟化的:time 包函数基于虚拟时钟运行,且如果气泡中的所有 goroutine 都处于阻塞状态,时钟会瞬间向前推进。

Wait 函数等待当前气泡中的所有 goroutine 阻塞。

该包最初在 Go 1.24 中以 GOEXPERIMENT=synctest 形式提供,API 略有不同。现在该实验已毕业并正式可用。如果设置了 GOEXPERIMENT=synctest,旧 API 仍然存在,但会在 Go 1.26 中移除。

新的实验性 encoding/json/v2 包

Go 1.25 包含一个新的实验性 JSON 实现,可在构建时通过设置环境变量 GOEXPERIMENT=jsonv2 启用。

启用后,有两个新包可用:

  • encoding/json/v2 包:encoding/json 包的重大修订版。
  • encoding/json/jsontext 包:提供 JSON 语法的底层处理。

此外,当启用 “jsonv2” GOEXPERIMENT 时:

  • encoding/json 包使用新的 JSON 实现。序列化和反序列化行为不受影响,但包函数返回的错误文本可能会变化。
  • encoding/json 包包含许多可用于配置序列化器和反序列化器的新选项。

在许多场景下,新实现的性能显著优于现有实现。一般来说,两者的序列化性能相当,而新实现的反序列化性能明显更快。更多详细分析请参见 github.com/go-json-experiment/jsonbench 仓库。

更多细节请参见提案 issue。

我们鼓励 encoding/json 的用户在启用 GOEXPERIMENT=jsonv2 的情况下测试他们的程序,以帮助发现与新实现的兼容性问题。

我们预计 encoding/json/v2 的设计会继续演进。鼓励开发者尝试新 API 并在提案 issue 上提供反馈。

库的次要变化

archive/tar

Writer.AddFS 实现现在支持实现 io/fs.ReadLinkFS 的文件系统的符号链接。

encoding/asn1

Unmarshal 和 UnmarshalWithParams 现在更一致地解析 ASN.1 类型 T61String 和 BMPString。这可能导致一些以前被接受的格式错误的编码现在被拒绝。

crypto

MessageSigner 是一个新的签名接口,可由希望自行对要签名的消息进行哈希的签名者实现。还引入了新函数 SignMessage,它尝试将 Signer 接口升级为 MessageSigner,如果成功则使用 MessageSigner.SignMessage 方法,否则使用 Signer.Sign。当代码希望同时支持 Signer 和 MessageSigner 时,可使用此函数。

程序启动后更改 GODEBUG 的 fips140 设置现在无效。以前,文档中注明不允许这样做,且更改可能导致恐慌。

在 amd64 上,当不支持 AVX2 指令时,SHA-1、SHA-256 和 SHA-512 现在更慢。2015 年以后生产的所有服务器处理器(以及大多数其他处理器)都支持 AVX2。

crypto/ecdsa

新的 ParseRawPrivateKeyParseUncompressedPublicKeyPrivateKey.Bytes 和 PublicKey.Bytes 函数及方法实现了底层编码,无需再使用 crypto/elliptic 或 math/big 的函数和方法。

当启用 FIPS 140-3 模式时,签名速度现在提高了四倍,与非 FIPS 模式的性能相当。

crypto/ed25519

当启用 FIPS 140-3 模式时,签名速度现在提高了四倍,与非 FIPS 模式的性能相当。

crypto/elliptic

某些 Curve 实现上隐藏且未文档化的 Inverse 和 CombinedMult 方法已被移除。

crypto/rsa

PublicKey 不再声称模数是保密的。VerifyPKCS1v15 和 VerifyPSS 早已警告所有输入都是公开的且可能被泄露,并且有一些数学攻击可以从其他公开值中恢复模数。

密钥生成现在快了三倍。

crypto/sha1

在 amd64 上,当支持 SHA-NI 指令时,哈希速度现在快了两倍。

crypto/sha3

新的 SHA3.Clone 方法实现了 hash.Cloner

在 Apple M 处理器上,哈希速度现在快了两倍。

crypto/tls

新的 ConnectionState.CurveID 字段公开了用于建立连接的密钥交换机制。

新的 Config.GetEncryptedClientHelloKeys 回调可用于为服务器设置加密客户端问候(Encrypted Client Hello)扩展的 EncryptedClientHelloKeys

根据 RFC 9155,TLS 1.2 握手现在禁止使用 SHA-1 签名算法。可通过 GODEBUG=tlssha1=1 重新启用。

当启用 FIPS 140-3 模式时,TLS 1.2 现在要求使用扩展主密钥(Extended Master Secret),且允许使用 Ed25519 和 X25519MLKEM768。

TLS 服务器现在优先选择最高支持的协议版本,即使它不是客户端最偏好的协议版本。

TLS 客户端和服务器现在在遵循规范和拒绝非规范行为方面更加严格。与合规对等方的连接应不受影响。

crypto/x509

CreateCertificateCreateCertificateRequest 和 CreateRevocationList 现在可接受 crypto.MessageSigner 签名接口以及 crypto.Signer。这允许这些函数使用实现 “一次性” 签名接口的签名者,其中哈希由签名操作本身完成,而非调用者。

CreateCertificate 现在在 SubjectKeyId 缺失时使用截断的 SHA-256 来填充。GODEBUG=x509sha256skid=0 设置可恢复为使用 SHA-1。

ParseCertificate 现在拒绝包含 BasicConstraints 扩展且 pathLenConstraint 为负数的证书。

ParseCertificate 现在更一致地处理使用 ASN.1 T61String 和 BMPString 类型编码的字符串。这可能导致一些以前被接受的格式错误的编码现在被拒绝。

debug/elf

debug/elf 包添加了两个新常量:

  • PT_RISCV_ATTRIBUTES
  • 用于 RISC-V ELF 解析的 SHT_RISCV_ATTRIBUTES
go/ast

FilterPackagePackageExportsMergePackageFiles 函数,以及 MergeMode 类型及其常量均已弃用,因为它们仅用于早已弃用的 Object 和 Package 机制。

新的 PreorderStack 函数与 Inspect 类似,会遍历语法树并提供对子树遍历的控制,此外还方便地在每个节点处提供封闭节点的栈。

go/parser

ParseDir 函数已弃用。

go/token

新的 FileSet.AddExistingFiles 方法允许将现有 File 添加到 FileSet,或为任意一组 File 构建 FileSet,从而缓解长期运行的应用程序中单个全局 FileSet 带来的问题。

go/types

Var 现在有一个 Var.Kind 方法,将变量分类为以下之一:包级变量、接收器、参数、返回值、局部变量或结构体字段。

新的 LookupSelection 函数查找给定名称和接收器类型的字段或方法,与现有的 LookupFieldOrMethod 函数类似,但返回 Selection 形式的结果。

hash

新的 XOF 接口可由 “可扩展输出函数”(XOF)实现,这些函数是具有任意或无限输出长度的哈希函数,如 SHAKE。

实现新 Cloner 接口的哈希可以返回其状态的副本。所有标准库哈希实现现在都实现了 Cloner

hash/maphash

新的 Hash.Clone 方法实现了 hash.Cloner

io/fs

新的 ReadLinkFS 接口提供读取文件系统中符号链接的能力。

log/slog

GroupAttrs 从 Attr 值切片创建一个组 Attr

Record 现在有一个 Source 方法,返回其源位置或 nil(如果不可用)。

mime/multipart

新的辅助函数 FileContentDisposition 构建多部分 Content-Disposition 头字段。

net

LookupMX 和 Resolver.LookupMX 现在返回看起来像有效 IP 地址的 DNS 名称以及有效域名。以前,如果名称服务器返回 IP 地址作为 DNS 名称,LookupMX 会按照 RFC 要求丢弃它。但实际上,名称服务器有时确实会返回 IP 地址。

在 Windows 上,ListenMulticastUDP 现在支持 IPv6 地址。

在 Windows 上,现在可以在 os.File 和网络连接之间进行转换。具体来说,FileConnFilePacketConn 和 FileListener 函数现已实现,返回与打开文件对应的网络连接或监听器。类似地,TCPConnUDPConnUnixConnIPConnTCPListener 和 UnixListener 的 File 方法现已实现,返回网络连接的底层 os.File

net/http

新的 CrossOriginProtection 通过拒绝不安全的跨域浏览器请求来实现对跨站请求伪造(CSRF)的保护。它使用现代浏览器的 Fetch 元数据,不需要令牌或 cookie,并支持基于源和模式的绕过。

os

在 Windows 上,NewFile 现在支持为异步 I/O 打开的句柄(即 syscall.CreateFile 调用中指定了 syscall.FILE_FLAG_OVERLAPPED)。这些句柄与 Go 运行时的 I/O 完成端口相关联,这为生成的 File 带来以下好处:

  • I/O 方法(File.ReadFile.WriteFile.ReadAt 和 File.WriteAt)不会阻塞 OS 线程。
  • 支持截止时间方法(File.SetDeadlineFile.SetReadDeadline 和 File.SetWriteDeadline)。

此增强对在 Windows 上通过命名管道通信的应用程序特别有益。

请注意,一个句柄一次只能与一个完成端口相关联。如果提供给 NewFile 的句柄已与完成端口相关联,返回的 File 会降级为同步 I/O 模式。在这种情况下,I/O 方法会阻塞 OS 线程,且截止时间方法无效。

DirFS 和 Root.FS 返回的文件系统实现了新的 io/fs.ReadLinkFS 接口。CopyFS 在复制实现 io/fs.ReadLinkFS 的文件系统时支持符号链接。

Root 类型支持以下附加方法:
Root.ChmodRoot.ChownRoot.ChtimesRoot.LchownRoot.LinkRoot.MkdirAllRoot.ReadFileRoot.ReadlinkRoot.RemoveAllRoot.RenameRoot.SymlinkRoot.WriteFile

reflect

新的 TypeAssert 函数允许将 Value 直接转换为给定类型的 Go 值。这类似于对 Value.Interface 的结果使用类型断言,但避免了不必要的内存分配。

regexp/syntax

\p{name} 和 \P{name} 字符类语法现在接受名称 AnyASCIIAssignedCn 和 LC,以及 Unicode 类别别名(如 \p{Letter} 对应 \pL)。根据 Unicode TR18,它们现在还使用不区分大小写的名称查找,忽略空格、下划线和连字符。

runtime

AddCleanup 调度的清理函数现在并发且并行执行,这使得清理更适合频繁使用(如 unique 包)。请注意,如果个别清理操作必须执行长时间任务或阻塞,仍应将其工作分流到新的 goroutine,以避免阻塞清理队列。

新的 GODEBUG=checkfinalizers=1 设置有助于发现终结器和清理操作的常见问题(如 GC 指南中描述的那些)。在此模式下,运行时在每个垃圾收集周期运行诊断,并定期向 stderr 报告终结器和清理队列长度,以帮助识别长时间运行的终结器和 / 或清理操作的问题。更多细节请参见 GODEBUG 文档。

新的 SetDefaultGOMAXPROCS 函数将 GOMAXPROCS 设置为运行时默认值,就像未设置环境变量一样。如果 GOMAXPROCS 已被环境变量或之前的 GOMAXPROCS 调用禁用,此函数有助于启用新的 GOMAXPROCS 默认行为。

runtime/pprof

关于运行时内部锁争用的互斥锁概要文件现在正确指向导致延迟的临界区末尾。这与针对 sync.Mutex 值争用的概要文件行为一致。GODEBUG 中用于 runtimecontentionstacks 的设置(允许选择 Go 1.22 到 1.24 中此部分概要文件的特殊行为)现已移除。

sync

新的 WaitGroup.Go 方法使创建和计数 goroutine 的常见模式更便捷。

testing

T.AttrB.Attr 和 F.Attr 新方法向测试日志输出一个属性。属性是与测试相关联的任意键值对。

例如,在名为 TestF 的测试中,t.Attr("key", "value") 输出:

plaintext

=== ATTR  TestF key value

使用 -json 标志时,属性会以新的 “attr” 动作出现。

TB 和 F 的新 Output 方法提供一个 io.Writer,其输出写入与 TB.Log 相同的测试输出流。与 TB.Log 一样,输出会缩进,但不包含文件和行号。

如果并行测试正在运行,AllocsPerRun 函数现在会恐慌。如果有其他测试在运行,AllocsPerRun 的结果本质上是不稳定的。新的恐慌行为有助于发现此类错误。

testing/fstest

MapFS 实现了新的 io/fs.ReadLinkFS 接口。TestFS 会验证 io/fs.ReadLinkFS 接口的功能(如果已实现)。TestFS 不再跟随符号链接,以避免无限递归。

unicode

新的 CategoryAliases 映射提供类别别名名称的访问(如 “Letter” 对应 “L”)。

新的类别 Cn 和 LC 分别定义未分配的代码点和大小写字母。这些在 Unicode 中一直有定义,但在早期 Go 版本中被不慎遗漏。C 类别现在包含 Cn,这意味着它已添加所有未分配的代码点。

unique

unique 包现在更积极、更高效且并行地回收 interned 值。因此,使用 Make 的应用程序在 intern 大量真正唯一的值时,不太可能出现内存膨胀。

以前,传递给 Make 且包含 Handle 的值需要多个垃圾收集周期才能回收(与 Handle 值链的深度成正比)。现在,一旦不再使用,它们会在单个周期内被及时回收。

端口

Darwin

如 Go 1.24 发布说明中所宣布,Go 1.25 需要 macOS 12 Monterey 或更高版本。已停止支持旧版本。

Windows

Go 1.25 是包含有问题的 32 位 windows/arm 端口(GOOS=windows GOARCH=arm)的最后一个版本。它将在 Go 1.26 中移除。

Loong64

linux/loong64 端口现在支持竞态检测器、使用 runtime.SetCgoTraceback 从 C 代码收集回溯信息,以及使用内部链接模式链接 cgo 程序。

RISC-V

linux/riscv64 端口现在支持 plugin 构建模式。

环境变量 GORISCV64 现在接受新值 rva23u64,用于选择 RVA23U64 用户模式应用程序配置文件。

http://www.lryc.cn/news/619558.html

相关文章:

  • ant-design a-from-model的校验
  • 自然语言处理的实际应用
  • OpenAI官方写的GPT-5 prompt指南
  • [C语言]第二章-从Hello World到头文件
  • 服务器硬件电路设计之 I2C 问答(五):I2C 总线数据传输方向如何确定、信号线上的串联电阻有什么作用?
  • Vue实时刷新,比如我提交审核,审核页面还需要点查询才能看到最新数据
  • 广州健永信息科技有限公司发展历程
  • 【分布式 ID】一文详解美团 Leaf
  • ubuntu24.04安装 bpftool 以及生成 vmlinux.h 文件
  • MySQL的MVCC多版本并发控制
  • 拓扑结构图解析
  • iscc2025区域赛wp
  • GitHub宕机时的协作方案
  • 软考备考——三、操作系统
  • 【计组】指令与CPU
  • 建设有人文温度的智能社会:规划与实施路径
  • Apple 的 GPU 加速框架
  • setsockopt函数详解
  • 利用 Makefile 高效启动 VIVADO 软件:深入解析与实践
  • 哈希算法(摘要算法)
  • 超实用!ToDesk/网易UU/向日葵:远程办公文件协作效率与安全实测
  • C++冒泡、选择、快速、桶排序超超超详细解析
  • PCBA:电子产品制造的核心环节
  • 深度学习赋能汽车制造缺陷检测
  • MFC/C++ 如何弹窗选择具体文件或某种类型文件路径,又是如何选择路径
  • 记录RK3588的docker中启动rviz2报错
  • 【论文笔记】DOC: Improving Long Story Coherence With Detailed Outline Control
  • 【114页PPT】基于SAPSRM数字化采购解决方案(附下载方式)
  • XCZU6CG-2FFVC900I Xilinx FPGA AMD ZynqUltraScale+ MPSoC
  • 002.从0开始,实现第一个deepseek问答