Go 1.19 新特性速览

16,797

Go 1.19 发布草案简介

Go 1.19 尚未发布,预计于 2022 年 8 月正式发布。

  • 语言的变化

语言只有一个很小的变化,对方法声明中类型参数的范围进行了修正,对现有程序没有影响。

  • 记忆模型

Go 内存模型经过修改,使得 Go 与 C、C++、Java、JavaScript、Rust 和 Swift 使用的内存模型保持一致 。之前,Go 只提供顺序一致的原子性,而不像其他语言那么灵活。随着内存模型的更新,Go 1.19在包中引入了新的类型sync/atomic ,让使用原子性更加容易,例如 atomic.Int64 和 atomic.Pointer[T]

  • 端口

龙芯64位

Go 1.19 在 Linux 上增加了对龙芯 64 位架构 LoongArch 的支持(GOOS=linuxGOARCH=loong64) 。

RISC-V

riscv64端口现在支持使用寄存器传递函数参数和结果。

  • 工具

文档评论

Go 1.19 在文档注释中添加了对链接、列表和更清晰标题的支持。作为此更改的一部分,gofmt 现在支持重新格式化文档注释以使其呈现的含义更清晰,并支持将它们呈现为 HTML、Markdown 和文本的形式。

新的unix构建约束

unix现在可以按//go:build行识别构建约束。如果目标操作系统(也称为GOOS)是 Unix 或类 Unix 系统,则满足约束。对于 1.19 版本,如果GOOS是 aixandroiddarwindragonflyfreebsdhurdillumosioslinuxnetbsdopenbsd,solaris,即满足约束条件。在之后的版本中,该unix约束可能会支持其他操作系统。

执行命令

如果配置-trimpath标志,可以标记到 Go 二进制文件中,并且支持使用 go version -m 或者debug.ReadBuildInfo进行验证。

go generate现在支持显示得设置GOROOT环境变量,即使是在已经使用-trimpath的情况下。

  • 运行时

运行时现在包括对软内存限制的支持。此内存限制包括 Go 堆和运行时管理的所有其他内存,不包括外部内存源,例如二进制文件本身的映射、以其他语言管理的内存以及操作系统代表 Go 程序持有的内存。这个限制可以通过 runtime/debug.SetMemoryLimit 或等效的 GOMEMLIMIT 环境变量来管理。该限制与 runtime/debug.SetGCPercent/GOGC 一起使用。当设置GOGC=off,允许 Go 程序始终最大限度地利用其内存限制,在某些情况下提高资源效率。

为了在程序的活动堆大小接近软内存限制时限制 GC 抖动的影响,Go 运行时还尝试将总 GC CPU 利用率限制为 50%,不包括空闲时间,选择使用更多内存而不是阻止应用程序进展。

当应用程序空闲到足以强制执行周期性 GC 周期时,在空闲操作系统线程上调度的 GC 工作 goroutine 会更少。

在 Unix 操作系统上,导入包 os的 Go 程序现在会自动将打开文件限制 ( RLIMIT_NOFILE) 增加到允许的最大值;也就是说,他们更改软限制以匹配硬限制。这更正了在某些系统上人为设置的下限,以便与使用select系统调用的非常旧的 C 程序兼容 。

针对不可恢复的致命错误(例如并发映射写入,或解锁未锁定的互斥锁),现在会打印更简单的回溯信息,不包括运行时元数据(相当于致命恐慌),除非GOTRACEBACK=system或者crash,否则运行时会溯源所有的堆栈信息。

在 ARM64 上添加了对调试器注入函数调用的支持,使用户能够在使用经过更新以利用此功能的调试器时,在交互式调试会话中从其二进制文件调用函数。

  • 编译器

编译器使用跳转表来实现大整数和字符串 switch 语句。尽管 switch 语句的性能表现各不相同,但基本上可以快 20% 左右。(注意:只有GOARCH=amd64GOARCH=arm64的系统支持)

Go 编译器现在需要该-p=importpath标志来构建可链接的目标文件。这已经由go命令和 Bazel 提供。任何其他直接调用 Go 编译器的构建系统都需要确保它们也传递了这个标志。

  • 汇编器

与编译器一样,汇编器需要使用 -p=importpath标志来构建可链接的目标文件。任何其他直接调用 Go 汇编器的构建系统都需要确保它们也传递了这个标志。

  • 链接器

在 ELF 平台上,链接器现在以标准 gABI 格式 ( SHF_COMPRESSED) 发出压缩的 DWARF 部分,而不是传统.zdebug格式。

  • 核心库

新的原子类型

sync/atomic包定义了新类型: BoolInt32Int64Uint32Uint64Uintptr, 和 Pointer

路径查找

Command和 LookPath不再允许使用相对路径搜索 PATH 地址。这消除了常见的安全问题来源, 但也可能破坏现有的程序。

在 Windows 上,CommandLookPath依赖 NoDefaultCurrentDirectoryInExePath 环境变量,.在 Windows 系统的 PATH 查找中会被默认禁用。

相关库的小改动

与往常一样,在考虑到对 Go 1的兼容性的前提下,对库进行了各种细微的更改和更新,还有各种性能的提升,这里就不一一列举了。