Go 1.18 发布说明
Go 1.18 简介
最新的 Go 版本 1.18 是一个重要版本,包含语言、工具链实现、运行时和库的更改。Go 1.18 在 Go 1.17 发布七个月后到来。与往常一样,该版本保持了 Go 1 兼容性承诺。我们预计几乎所有 Go 程序都将像以前一样继续编译和运行。
语言变化
泛型
Go 1.18 包含了 类型参数提案 中描述的泛型功能的实现。这包括语言的重大(但完全向后兼容)更改。
这些新的语言更改需要大量尚未在生产环境中进行大量测试的新代码。只有当更多人编写和使用泛型代码时,这种情况才会发生。我们相信此功能实现良好且质量高。然而,与 Go 的大多数方面不同,我们无法用实际经验来支持这种信念。因此,虽然我们鼓励在有意义的地方使用泛型,但在生产环境中部署泛型代码时,请谨慎使用。
虽然我们相信新的语言特性设计良好且规范清晰,但我们可能犯了错误。我们想强调的是,Go 1 兼容性保证 声明“如果需要解决规范中的不一致或不完整,解决问题可能会影响现有程序的含义或合法性。我们保留解决此类问题的权利,包括更新实现。”它还声明“如果编译器或库存在违反规范的错误,如果修复该错误,依赖于该错误行为的程序可能会中断。我们保留修复此类错误的权利。”换句话说,可能会有一些使用泛型的代码在 1.18 版本中可以工作,但在后续版本中会中断。我们不计划也不期望进行任何此类更改。然而,在未来的版本中中断 1.18 程序可能由于我们目前无法预见的原因而变得必要。我们将尽可能减少任何此类中断,但我们不能保证中断为零。
以下是最显著的更改列表。有关更全面的概述,请参阅 提案。有关详细信息,请参阅 语言规范。
- 函数 和 类型声明 的语法现在接受 类型参数。
- 可以通过在参数化函数和类型后添加方括号中的类型参数列表来实例化它们。
- 新标记
~
已添加到 运算符和标点符号 集中。 - 接口类型 的语法现在允许嵌入任意类型(不仅仅是接口的类型名称)以及联合和
~T
类型元素。此类接口只能用作类型约束。接口现在定义了一组类型以及一组方法。 - 新的 预声明标识符
any
是空接口的别名。它可以用作interface{}
的替代。 - 新的 预声明标识符
comparable
是一个接口,表示所有可以使用==
或!=
进行比较的类型集合。它只能用作(或嵌入在)类型约束中。
有三个使用泛型的实验性包可能很有用。这些包位于 x/exp 仓库中;它们的 API 不受 Go 1 保证的覆盖,并且可能会随着我们对泛型经验的增加而更改。
golang.org/x/exp/constraints
对泛型代码有用的约束,例如 constraints.Ordered
。
golang.org/x/exp/slices
在任何元素类型的切片上操作的泛型函数集合。
golang.org/x/exp/maps
在任何键或元素类型的映射上操作的泛型函数集合。
当前的泛型实现有以下已知限制:
- Go 编译器无法处理泛型函数或方法中的类型声明。我们希望在未来版本中提供对此功能的支持。
-
Go 编译器不接受带有预声明函数
real
、imag
和complex
的类型参数类型的参数。我们希望在未来版本中消除此限制。 -
Go 编译器仅支持在类型参数类型
P
的值x
上调用方法m
,如果m
由P
的约束接口显式声明。类似地,方法值x.m
和方法表达式P.m
也仅在m
由P
显式声明时才受支持,即使m
可能是P
的方法集中的成员,因为P
中的所有类型都实现了m
。我们希望在未来版本中消除此限制。 -
Go 编译器不支持访问结构字段
x.f
,其中x
是类型参数类型,即使类型参数类型集中的所有类型都具有字段f
。我们可能会在未来版本中消除此限制。 - 不允许将类型参数或指向类型参数的指针作为未命名字段嵌入到结构类型中。类似地,不允许将类型参数嵌入到接口类型中。目前尚不清楚是否会允许这些操作。
- 具有多个项的联合元素可能不包含具有非空方法集的接口类型。目前尚不清楚是否会允许此操作。
泛型也代表着 Go 生态系统的一次重大变革。虽然我们已经更新了几个核心工具以支持泛型,但还有很多工作要做。其余工具、文档和库需要时间来跟上这些语言更改。
Bug 修复
Go 1.18 编译器现在会正确报告函数文字内部设置但从未使用过的变量的 declared but not used
错误。在 Go 1.18 之前,编译器在这种情况下不会报告错误。这修复了长期存在的编译器问题 #8560。由于此更改,(可能不正确的)程序可能无法再编译。必要的修复很简单:如果程序确实不正确,则修复它,或者使用有问题的变量,例如将其分配给空白标识符 _
。由于 go vet
总是指出此错误,受影响的程序数量可能非常少。
Go 1.18 编译器现在在将 rune 常量表达式(例如 '1' << 32
)作为参数传递给预声明函数 print
和 println
时报告溢出,这与用户定义函数的行为一致。在 Go 1.18 之前,编译器在这种情况下不会报告错误,而是静默接受此类常量参数,如果它们适合 int64
。由于此更改,(可能不正确的)程序可能无法再编译。必要的修复很简单:如果程序确实不正确,则修复它,或者将有问题的参数显式转换为正确的类型。由于 go vet
总是指出此错误,受影响的程序数量可能非常少。
移植
AMD64
Go 1.18 引入了新的 GOAMD64
环境变量,该变量在编译时选择 AMD64 架构的最小目标版本。允许的值为 v1
、v2
、v3
或 v4
。每个更高级别都需要并利用额外的处理器功能。详细说明可以在 此处 找到。
GOAMD64
环境变量默认为 v1
。
RISC-V
Linux 上的 64 位 RISC-V 架构(linux/riscv64
端口)现在支持 c-archive
和 c-shared
构建模式。
Linux
Go 1.18 需要 Linux 内核版本 2.6.32 或更高版本。
Windows
windows/arm
和 windows/arm64
端口现在支持非协作抢占,将该功能引入所有四个 Windows 端口,这有望解决在调用长时间阻塞的 Win32 函数时遇到的微妙错误。
iOS
在 iOS(ios/arm64
端口)和运行在 AMD64-based macOS 上的 iOS 模拟器(ios/amd64
端口)上,Go 1.18 现在需要 iOS 12 或更高版本;对先前版本的支持已停止。
FreeBSD
Go 1.18 是最后一个支持 FreeBSD 11.x 的版本,该版本已达到生命周期结束。Go 1.19 将需要 FreeBSD 12.2+ 或 FreeBSD 13.0+。FreeBSD 13.0+ 将需要设置了 COMPAT_FREEBSD12 选项的内核(这是默认设置)。
工具
模糊测试
Go 1.18 包含了 模糊测试提案 中描述的模糊测试实现。
请参阅 模糊测试登陆页面 以开始使用。
请注意,模糊测试会消耗大量内存,并可能在运行时影响您的机器性能。另请注意,模糊测试引擎在运行时会将扩展测试覆盖率的值写入 $GOCACHE/fuzz
中的模糊测试缓存目录。目前对模糊测试缓存中可以写入的文件数量或总字节数没有限制,因此它可能会占用大量存储空间(可能达到几个 GB)。
Go 命令
go
get
go
get
在模块感知模式下不再构建或安装包。go
get
现在专门用于调整 go.mod
中的依赖项。实际上,-d
标志始终启用。要在当前模块上下文之外安装可执行文件的最新版本,请使用 go
install
example.com/cmd@latest
。任何 版本查询 都可以代替 latest
。这种形式的 go
install
是在 Go 1.16 中添加的,因此支持旧版本的项目可能需要提供 go
install
和 go
get
的安装说明。当在模块外部使用时,go
get
现在会报告错误,因为没有 go.mod
文件可供更新。在 GOPATH 模式下(使用 GO111MODULE=off
),go
get
仍然像以前一样构建和安装包。
自动 go.mod
和 go.sum
更新
go
mod
graph
、go
mod
vendor
、go
mod
verify
和 go
mod
why
子命令不再自动更新 go.mod
和 go.sum
文件。(这些文件可以使用 go
get
、go
mod
tidy
或 go
mod
download
显式更新。)
go
version
go
命令现在将版本控制信息嵌入到二进制文件中。它包括当前检出的修订版、提交时间以及一个标志,指示是否存在已编辑或未跟踪的文件。如果 go
命令是在 Git、Mercurial、Fossil 或 Bazaar 仓库内的目录中调用的,并且 main
包及其包含的主模块位于同一仓库中,则会嵌入版本控制信息。此信息可以使用 -buildvcs=false
标志省略。
此外,go
命令还嵌入了有关构建的信息,包括构建和工具标签(使用 -tags
设置)、编译器、汇编器和链接器标志(如 -gcflags
)、cgo 是否启用,如果启用,cgo 环境变量(如 CGO_CFLAGS
)的值。VCS 和构建信息都可以与模块信息一起使用 go
version
-m
file
或 runtime/debug.ReadBuildInfo
(对于当前运行的二进制文件)或新的 debug/buildinfo
包读取。
嵌入式构建信息的底层数据格式可能会随 Go 新版本而变化,因此较旧版本的 go
可能无法处理由较新版本 go
生成的构建信息。要从用 go
1.18 构建的二进制文件中读取版本信息,请使用 go
1.18+ 中的 go
version
命令和 debug/buildinfo
包。
go
mod
download
如果主模块的 go.mod
文件指定 go
1.17
或更高版本,则不带参数的 go
mod
download
现在仅下载主模块 go.mod
文件中显式 所需 模块的源代码。(在 go
1.17
或更高版本的模块中,该集合已经包含构建主模块中的包和测试所需的所有依赖项。)要同时下载传递依赖项的源代码,请使用 go
mod
download
all
。
go
mod
vendor
go
mod
vendor
子命令现在支持 -o
标志来设置输出目录。(其他 go
命令在使用 -mod=vendor
加载包时仍从模块根目录的 vendor
目录读取,因此此标志的主要用途是用于需要收集包源代码的第三方工具。)
go
mod
tidy
go
mod
tidy
命令现在会在 go.sum
文件中保留额外的校验和,用于验证 构建列表 中每个导入的包是否仅由一个模块提供所需的模块源代码。因为这种情况很少见,而且未能应用会导致构建错误,所以此更改 不 受主模块 go.mod
文件中的 go
版本限制。
go
work
go
命令现在支持“工作区”模式。如果在工作目录或父目录中找到 go.work
文件,或者使用 GOWORK
环境变量指定了文件,它将使 go
命令进入工作区模式。在工作区模式下,将使用 go.work
文件来确定用作模块解析根的主模块集,而不是使用通常找到的 go.mod
文件来指定单个主模块。有关更多信息,请参阅 go work
文档。
go
build
-asan
go
build
命令和相关命令现在支持 -asan
标志,该标志启用与使用地址清理器编译的 C(或 C++)代码(C 编译器选项 -fsanitize=address
)的互操作。
go
test
go
命令现在支持上述新 模糊测试支持 的附加命令行选项
go test
支持-fuzz
、-fuzztime
和-fuzzminimizetime
选项。有关这些选项的文档,请参阅go help testflag
。go clean
支持-fuzzcache
选项。有关文档,请参阅go help clean
。
//go:build
行
Go 1.17 引入了 //go:build
行,作为编写构建约束的一种更具可读性的方式,而不是 //
+build
行。从 Go 1.17 开始,gofmt
会添加 //go:build
行以匹配现有的 +build
行并保持同步,而 go
vet
会诊断它们不同步的情况。
由于 Go 1.18 版本的发布标志着对 Go 1.16 支持的结束,所有受支持的 Go 版本现在都理解 //go:build
行。在 Go 1.18 中,go
fix
现在会删除在其 go.mod
文件中声明 go
1.18
或更高版本的模块中现已过时的 //
+build
行。
有关更多信息,请参阅 go.dev/design/draft-gobuild。
Gofmt
gofmt
现在并发读取和格式化输入文件,内存限制与 GOMAXPROCS
成比例。在多 CPU 机器上,gofmt
现在应该明显更快。
Vet
泛型更新
vet
工具已更新以支持泛型代码。在大多数情况下,只要在将类型参数替换为其 类型集 中的类型后,它会在等效的非泛型代码中报告错误,它就会在泛型代码中报告错误。例如,vet
会报告以下格式错误:
func Print[T ~int|~string](t T) {
fmt.Printf("%d", t)
}
因为它会在 Print[string]
的非泛型等效代码中报告格式错误。
func PrintString(x string) {
fmt.Printf("%d", x)
}
现有检查器的精度改进
cmd/vet
检查器 copylock
、printf
、sortslice
、testinggoroutine
和 tests
都已获得适度的精度改进,以处理额外的代码模式。这可能会导致现有包中报告新的错误。例如,printf
检查器现在会跟踪通过连接字符串常量创建的格式字符串。因此 vet
将在以下代码中报告错误:
// fmt.Printf formatting directive %d is being passed to Println.
fmt.Println("%d"+` ≡ x (mod 2)`+"\n", x%2)
运行时
垃圾收集器现在在确定运行频率时包含非堆垃圾收集器工作源(例如,堆栈扫描)。因此,当这些源很重要时,垃圾收集器开销更具可预测性。对于大多数应用程序,这些更改可以忽略不计;但是,一些 Go 应用程序现在可能比以前使用更少的内存并花费更多时间进行垃圾收集,反之亦然。预期的解决方法是在必要时调整 GOGC
。
运行时现在更有效地将内存返回给操作系统,并且因此进行了更积极的调整。
Go 1.17 通常改进了堆栈跟踪中参数的格式,但可能会打印寄存器中传递的参数的不准确值。Go 1.18 通过在每个可能不准确的值后面打印问号 (?
) 来改进这一点。
内置函数 append
在必须分配新的底层数组时,在决定切片增长多少时使用略有不同的公式。新公式不太容易出现分配行为的突然转变。
编译器
Go 1.17 实现 了一种新的方法,在某些操作系统上使用寄存器而不是堆栈传递函数参数和结果,用于 64 位 x86 架构。Go 1.18 将支持的平台扩展到包括 64 位 ARM (GOARCH=arm64
)、大端和小端 64 位 PowerPC (GOARCH=ppc64
、ppc64le
),以及所有操作系统上的 64 位 x86 架构 (GOARCH=amd64
)。在 64 位 ARM 和 64 位 PowerPC 系统上,基准测试显示典型性能提升 10% 或更多。
如 Go 1.17 发布说明中 所述,此更改不影响任何安全 Go 代码的功能,旨在对大多数汇编代码没有影响。有关更多详细信息,请参阅 Go 1.17 发布说明。
编译器现在可以内联包含范围循环或带标签的 for 循环的函数。
新的 -asan
编译器选项支持新的 go
命令 -asan
选项。
由于编译器类型检查器已完全替换以支持泛型,因此某些错误消息现在可能使用与以前不同的措辞。在某些情况下,Go 1.18 之前的错误消息提供了更多详细信息或措辞更具帮助性。我们打算在 Go 1.19 中解决这些情况。
由于编译器中与支持泛型相关的更改,Go 1.18 编译速度可能比 Go 1.17 编译速度慢大约 15%。编译代码的执行时间不受影响。我们打算在未来版本中提高编译器的速度。
链接器
链接器发出的 重定位量大大减少。因此,大多数代码库链接速度更快,链接所需内存更少,并生成更小的二进制文件。处理 Go 二进制文件的工具应使用 Go 1.18 的 debug/gosym
包来透明地处理旧的和新的二进制文件。
新的 -asan
链接器选项支持新的 go
命令 -asan
选项。
引导
从源代码构建 Go 版本时,如果未设置 GOROOT_BOOTSTRAP
,则 Go 的早期版本会在 $HOME/go1.4
目录(Windows 上为 %HOMEDRIVE%%HOMEPATH%\go1.4
)中查找 Go 1.4 或更高版本的引导工具链。Go 现在首先查找 $HOME/go1.17
或 $HOME/sdk/go1.17
,然后才回退到 $HOME/go1.4
。我们打算让 Go 1.19 要求 Go 1.17 或更高版本进行引导,此更改应该使过渡更顺畅。有关更多详细信息,请参阅 go.dev/issue/44505。
标准库
新的 debug/buildinfo
包
新的 debug/buildinfo
包提供对 go
命令构建的可执行文件中嵌入的模块版本、版本控制信息和构建标志的访问。相同的信息也可以通过 runtime/debug.ReadBuildInfo
(对于当前运行的二进制文件)和命令行上的 go
version
-m
获得。
新的 net/netip
包
新的 net/netip
包定义了一个新的 IP 地址类型 Addr
。与现有的 net.IP
类型相比,netip.Addr
类型占用内存更少,是不可变的,并且可比较,因此它支持 ==
并可以用作映射键。
除了 Addr
,该包还定义了 AddrPort
(表示 IP 和端口)和 Prefix
(表示网络 CIDR 前缀)。
该包还定义了几个函数来创建和检查这些新类型:AddrFrom4
、AddrFrom16
、AddrFromSlice
、AddrPortFrom
、IPv4Unspecified
、IPv6LinkLocalAllNodes
、IPv6Unspecified
、MustParseAddr
、MustParseAddrPort
、MustParsePrefix
、ParseAddr
、ParseAddrPort
、ParsePrefix
、PrefixFrom
。
net
包包含新的方法,这些方法与现有方法并行,但返回 netip.AddrPort
而不是更重量级的 net.IP
或 *net.UDPAddr
类型:Resolver.LookupNetIP
、UDPConn.ReadFromUDPAddrPort
、UDPConn.ReadMsgUDPAddrPort
、UDPConn.WriteToUDPAddrPort
、UDPConn.WriteMsgUDPAddrPort
。新的 UDPConn
方法支持无分配 I/O。
如果未设置 可以通过设置 可以通过设置 与往常一样,库中有各种微小的更改和更新,这些都是在遵守 Go 1 兼容性承诺的前提下进行的。 新的 在对具有 新的 对无效曲线点(即 新的 当使用 nil 在 Windows、macOS 和 iOS 上,当 Go 1.19 中可能会删除对使用依赖于 MD5 哈希( 已添加 如果文件没有符号节,File.Symbols 方法现在返回新的导出错误值 ErrNoSymbols。 根据提案 向 go/ast 和 go/token 添加支持参数化函数和类型的功能,对 新的 根据提案 向 go/ast 和 go/token 添加支持参数化函数和类型的功能,新的常量 新的 根据提案 向 go/types 添加支持类型参数的功能,对 谓词 在 当参数不是最常见的图像类型时, 在 WebAssembly 目标上, 新的 新的 在查找包含非 ASCII 字符的域名时,Unicode 到 ASCII 的转换现在根据 Unicode IDNA 兼容性处理 标准 (UTS #46) 中定义的非过渡处理进行。四个不同的 rune 的解释发生了变化:ß、ς、零宽度连接符 U+200D 和零宽度非连接符 U+200C。非过渡处理与大多数应用程序和 Web 浏览器保持一致。 当 cgo 不可用时, 新的 新的 新的 已向 已添加 CPU 性能分析器现在在 Linux 上使用每线程计时器。这增加了性能分析可观察到的最大 CPU 使用率,并减少了某些形式的偏差。 新的 新的 新的方法 为 Windows 引入了新函数 FreeBSD 现在支持 如果 新的 在 该包通过新常量 新的 net
包现在还包括在现有 TCPAddr
/UDPAddr
类型和 netip.AddrPort
之间进行转换的函数和方法:TCPAddrFromAddrPort
、UDPAddrFromAddrPort
、TCPAddr.AddrPort
、客户端默认禁用 TLS 1.0 和 1.1
Config.MinVersion
,则对于客户端连接,它现在默认为 TLS 1.2。任何安全更新的服务器都应支持 TLS 1.2,并且自 2020 年以来浏览器已要求使用它。通过将 Config.MinVersion
设置为 VersionTLS10
,仍然支持 TLS 1.0 和 1.1。服务器端默认值保持不变为 TLS 1.0。GODEBUG=tls10default=1
环境变量暂时将默认值恢复为 TLS 1.0。此选项将在 Go 1.19 中删除。拒绝 SHA-1 证书
crypto/x509
现在将拒绝使用 SHA-1 哈希函数签名的证书。这不适用于自签名根证书。自 2017 年以来,针对 SHA-1 的实际攻击 已得到证实,并且自 2015 年以来,公开受信任的证书颁发机构未颁发 SHA-1 证书。GODEBUG=x509sha1=1
环境变量暂时恢复此功能。此选项将在未来版本中删除。对库的微小更改
bufio
Writer.AvailableBuffer
方法返回一个空缓冲区,该缓冲区可能具有非空容量,用于 append-like API。追加后,可以将缓冲区提供给后续的 Write
调用,并可能避免任何复制。nil
缓冲区的对象调用时,Reader.Reset
和 Writer.Reset
方法现在使用默认缓冲区大小。bytes
Cut
函数围绕分隔符切割 []byte
。它可以替换和简化许多常见的 Index
、IndexByte
、IndexRune
和 SplitN
用法。Trim
、TrimLeft
和 TrimRight
现在无分配,尤其对于小的 ASCII 剪切集,速度提高了 10 倍。Title
函数现已弃用。它不处理 Unicode 标点符号和特定语言的字母大写规则,并已被 golang.org/x/text/cases 包取代。crypto/elliptic
P224
、P384
和 P521
曲线实现现在都由 addchain 和 fiat-crypto 项目生成的代码支持,后者基于经过形式化验证的算术运算模型。它们现在使用更安全的完整公式和内部 API。P-224 和 P-384 现在大约快四倍。所有特定的曲线实现现在都是恒定时间的。IsOnCurve
方法返回 false,且从未由 Unmarshal
或对有效点操作的 Curve
方法返回的点)进行操作一直是未定义的行为,可能导致密钥恢复攻击,并且新后端现在不支持。如果向 P224
、P384
或 P521
方法提供无效点,该方法现在将返回一个随机点。此行为在未来版本中可能会更改为显式 panic。crypto/tls
Conn.NetConn
方法允许访问底层的 net.Conn
。crypto/x509
VerifyOpts.Roots
调用 Certificate.Verify
或使用从 SystemCertPool
返回的根池时,它现在在 macOS 和 iOS 上使用平台 API 验证证书有效性。SystemCertPool
现在可在 Windows 上使用。SystemCertPool
返回的 CertPool
添加了额外的证书时,Certificate.Verify
将进行两次验证:一次使用平台验证器 API 和系统根,另一次使用 Go 验证器和额外的根。平台验证器 API 返回的链将优先。CertPool.Subjects
已弃用。在 Windows、macOS 和 iOS 上,由 SystemCertPool
返回的 CertPool
将返回一个不包含 Subjects
返回的切片中的系统根的池,因为静态列表无法适当表示平台策略,并且可能根本无法从平台 API 获取。MD5WithRSA
)的签名算法签署证书的支持。debug/dwarf
StructField
和 BasicType
结构体现在都有一个 DataBitOffset
字段,该字段保存 DW_AT_data_bit_offset
属性的值(如果存在)。debug/elf
R_PPC64_RELATIVE
常量。debug/plan9obj
embed
go:embed
指令现在可以以 all:
开头,以包含名称以点或下划线开头的文件。go/ast
go/ast
包进行了以下添加:
FuncType
和 TypeSpec
节点有一个新的字段 TypeParams
用于保存类型参数(如果有)。IndexListExpr
表示具有多个索引的索引表达式,用于具有多个显式类型参数的函数和类型实例化。go/constant
Kind.String
方法返回接收器类型的可读名称。go/token
TILDE
表示 ~
标记。go/types
Config.GoVersion
字段设置接受的 Go 语言版本。go/types
包进行了以下添加:
TypeParam
、工厂函数 NewTypeParam
及相关方法,以表示类型参数。TypeParamList
保存类型参数列表。TypeList
保存类型列表。NewSignatureType
分配一个带有(接收器或函数)类型参数的 Signature
。要访问这些类型参数,Signature
类型有两个新方法 Signature.RecvTypeParams
和 Signature.TypeParams
。Named
类型有四个新方法:Named.Origin
用于获取实例化类型的原始参数化类型,Named.TypeArgs
和 Named.TypeParams
用于获取实例化或参数化类型的类型参数或类型参数,以及 Named.SetTypeParams
用于设置类型参数(例如,在导入命名类型时,由于可能存在循环,命名类型的分配和类型参数的设置不能同时进行)。Interface
类型有四个新方法:Interface.IsComparable
和 Interface.IsMethodSet
用于查询接口定义的类型集的属性,以及 Interface.MarkImplicit
和 Interface.IsImplicit
用于设置和测试接口是否是类型约束文字周围的隐式接口。Union
和 Term
、工厂函数 NewUnion
和 NewTerm
及相关方法,以表示接口中的类型集。Instantiate
实例化一个参数化类型。Info.Instances
映射通过新的 Instance
类型记录函数和类型实例化。ArgumentError
及相关方法,以表示与类型参数相关的错误。Context
和工厂函数 NewContext
,以通过新的 Config.Context
字段促进跨类型检查包的相同类型实例的共享。AssignableTo
、ConvertibleTo
、Implements
、Identical
、IdenticalIgnoreTags
和 AssertableTo
现在也适用于是或包含泛型接口的参数,即只能在 Go 代码中用作类型约束的接口。请注意,对于未实例化的泛型类型参数,AssignableTo
、ConvertibleTo
、Implements
和 AssertableTo
的行为是未定义的,并且如果第一个参数是泛型接口,则 AssertableTo
是未定义的。html/template
range
管道中,新的 {{break}}
命令将提前结束循环,新的 {{continue}}
命令将立即开始下一次循环迭代。and
函数不再总是评估所有参数;它在第一个评估为 false 的参数之后停止评估参数。类似地,or
函数现在在第一个评估为 true 的参数之后停止评估参数。如果任何参数是函数调用,这会产生影响。image/draw
Draw
和 DrawMask
回退实现(用于这种情况)现在更快,如果这些参数实现了 Go 1.17 中添加的可选 draw.RGBA64Image
和 image.RGBA64Image
接口。net
net.Error.Temporary
已弃用。net/http
Transport
中的 Dial
、DialContext
、DialTLS
和 DialTLSContext
方法字段现在将被正确使用,如果指定,用于发出 HTTP 请求。Cookie.Valid
方法报告 cookie 是否有效。MaxBytesHandler
函数创建一个 Handler
,该 Handler 将其 ResponseWriter
和 Request.Body
包装在 MaxBytesReader
中。os/user
User.GroupIds
现在使用 Go 原生实现。reflect
Value.SetIterKey
和 Value.SetIterValue
方法使用映射迭代器作为源设置 Value。它们等效于 Value.Set(iter.Key())
和 Value.Set(iter.Value())
,但分配更少。Value.UnsafePointer
方法以 unsafe.Pointer
的形式返回 Value 的值。这允许调用者从 Value.UnsafeAddr
和 Value.Pointer
迁移,以消除在调用点执行 uintptr 到 unsafe.Pointer 转换的需要(如 unsafe.Pointer 规则所要求)。MapIter.Reset
方法更改其接收器以迭代不同的映射。使用 MapIter.Reset
允许对许多映射进行无分配迭代。Value
添加了许多方法(Value.CanInt
、Value.CanUint
、Value.CanFloat
、Value.CanComplex
)以测试转换是否安全。Value.FieldByIndexErr
以避免在通过 nil 指针步进到嵌入式结构体时 Value.FieldByIndex
中发生的 panic。reflect.Ptr
和 reflect.PtrTo
已分别重命名为 reflect.Pointer
和 reflect.PointerTo
,以与 reflect 包的其余部分保持一致。旧名称将继续有效,但在未来的 Go 版本中将被弃用。regexp
regexp
现在将 UTF-8 字符串的每个无效字节视为 U+FFFD
。runtime/debug
BuildInfo
结构体有两个新字段,包含有关二进制文件如何构建的额外信息:
GoVersion
保存用于构建二进制文件的 Go 版本。Settings
是一个 BuildSettings
结构体切片,保存描述构建的键/值对。runtime/pprof
strconv
strconv.Unquote
现在拒绝 Unicode 代理对。strings
Cut
函数围绕分隔符切割 string
。它可以替换和简化许多常见的 Index
、IndexByte
、IndexRune
和 SplitN
用法。Clone
函数复制输入 string
,而返回的克隆 string
不引用输入字符串的内存。Trim
、TrimLeft
和 TrimRight
现在无分配,尤其对于小的 ASCII 剪切集,速度提高了 10 倍。Title
函数现已弃用。它不处理 Unicode 标点符号和特定语言的字母大写规则,并已被 golang.org/x/text/cases 包取代。sync
Mutex.TryLock
、RWMutex.TryLock
和 RWMutex.TryRLock
将在当前未持有时获取锁。syscall
SyscallN
,允许调用任意数量的参数。因此,Syscall
、Syscall6
、Syscall9
、Syscall12
、Syscall15
和 Syscall18
已弃用,转而使用 SyscallN
。SysProcAttr.Pdeathsig
。syscall/js
Wrapper
接口已被移除。testing
-run
和 -bench
参数中 /
的优先级已提高。A/B|C/D
以前被视为 A/(B|C)/D
,现在被视为 (A/B)|(C/D)
。-run
选项没有选择任何测试,则忽略 -count
选项。这可能会在测试每次运行时更改子测试集的情况下,改变现有测试的行为(尽管这种情况不太可能发生)。testing.F
类型由上述新 模糊测试支持 使用。测试现在还支持命令行选项 -test.fuzz
、-test.fuzztime
和 -test.fuzzminimizetime
。text/template
range
管道中,新的 {{break}}
命令将提前结束循环,新的 {{continue}}
命令将立即开始下一次循环迭代。and
函数不再总是评估所有参数;它在第一个评估为 false 的参数之后停止评估参数。类似地,or
函数现在在第一个评估为 true 的参数之后停止评估参数。如果任何参数是函数调用,这会产生影响。text/template/parse
NodeBreak
和新类型 BreakNode
支持新的 text/template 和 html/template {{break}}
命令,并通过新常量 NodeContinue
和新类型 ContinueNode
支持新的 {{continue}}
命令。unicode/utf8
AppendRune
函数将 rune
的 UTF-8 编码附加到 []byte
。