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 编译器仅在
m
由P
的约束接口显式声明的情况下,才支持对类型参数类型P
的值x
调用方法m
。类似地,方法值x.m
和方法表达式P.m
也仅在m
由P
显式声明时才受支持,即使m
可能在P
的方法集中,原因是P
中的所有类型都实现了m
。我们希望在将来的版本中取消此限制。 -
Go 编译器不支持访问结构体字段
x.f
,其中x
是类型参数类型,即使类型参数的类型集中所有类型都具有字段f
。我们可能会在将来的版本中取消此限制。 - 在结构体类型中将类型参数或指向类型参数的指针嵌入为未命名字段是不允许的。类似地,在接口类型中嵌入类型参数也是不允许的。目前尚不清楚是否允许这些操作。
- 具有多个项的并集元素可能不包含具有非空方法集的接口类型。目前尚不清楚是否允许这些操作。
泛型也代表着 Go 生态系统的一次重大变化。虽然我们已经使用泛型支持更新了几个核心工具,但还有很多工作要做。剩余的工具、文档和库需要时间才能赶上这些语言更改。
错误修复
Go 1.18 编译器现在能够正确地报告函数字面量内设置但从未使用过的变量的 已声明但未使用
错误。在 Go 1.18 之前,编译器在这些情况下不会报告错误。这修复了长期存在的编译器问题 #8560。由于此更改,(可能是错误的)程序可能不再编译。必要的修复非常简单:如果程序实际上有误,则修复它,或者使用有问题的变量,例如将其分配给空白标识符 _
。由于 go vet
一直都指出了这个错误,因此受影响的程序数量可能非常少。
Go 1.18 编译器现在会在将诸如 '1' << 32
这样的 rune 常量表达式作为参数传递给预声明函数 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
在运行在基于 AMD64 的 macOS 上的 iOS(ios/arm64
端口)和 iOS 模拟器(ios/amd64
端口)上,Go 1.18 现在需要 iOS 12 或更高版本;对先前版本的支持已停止。
FreeBSD
Go 1.18 是最后一个在 FreeBSD 11.x 上受支持的版本,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
命令现在在二进制文件中嵌入版本控制信息。它包含当前签出的修订版、提交时间以及指示是否存在已编辑或未跟踪文件的状态。如果在 Git、Mercurial、Fossil 或 Bazaar 存储库中的目录中调用 go
命令,并且 main
包及其包含的主模块位于同一存储库中,则会嵌入版本控制信息。可以使用标志 -buildvcs=false
省略此信息。
此外,go
命令还嵌入有关构建的信息,包括构建和工具标签(使用 -tags
设置)、编译器、汇编器和链接器标志(如 -gcflags
)、cgo 是否启用,以及如果启用,cgo 环境变量的值(如 CGO_CFLAGS
)。可以使用 go
version
-m
file
或 runtime/debug.ReadBuildInfo
(对于当前正在运行的二进制文件)或新的 debug/buildinfo
包来读取 VCS 和构建信息以及模块信息。
嵌入式构建信息的底层数据格式可能会随着新的 Go 版本而改变,因此旧版本的 go
可能无法处理使用较新版本的 go
生成的构建信息。要从使用 go
1.18 构建的二进制文件中读取版本信息,请使用 go
version
命令和来自 go
1.18+ 的 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)
}
中报告格式错误
func PrintString(x string) {
fmt.Printf("%d", x)
}
因为它会在 Print[string]
的非泛型等效代码中报告格式错误
现有检查器的精度改进
// fmt.Printf formatting directive %d is being passed to Println.
fmt.Println("%d"+` ≡ x (mod 2)`+"\n", x%2)
cmd/vet
检查器 copylock
、printf
、sortslice
、testinggoroutine
和 tests
都进行了适度的精度改进,以处理更多代码模式。这可能会导致在现有包中报告新错误。例如,printf
检查器现在会跟踪通过连接字符串常量创建的格式字符串。因此,vet
将在
中报告错误
运行时
垃圾收集器现在在确定运行频率时包含垃圾收集器工作量的非堆源(例如,堆栈扫描)。因此,当这些源很重要时,垃圾收集器开销更易于预测。对于大多数应用程序来说,这些更改将微不足道;但是,某些 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
包
该包还定义了几个函数来创建和检查这些新类型: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。
net
包现在还包括函数和方法来在现有的 TCPAddr
/UDPAddr
类型和 netip.AddrPort
之间进行转换:TCPAddrFromAddrPort
、UDPAddrFromAddrPort
、TCPAddr.AddrPort
、UDPAddr.AddrPort
.
TLS 1.0 和 1.1 默认情况下在客户端禁用
如果 Config.MinVersion
未设置,它现在默认为客户端连接的 TLS 1.2。预计任何安全更新的服务器都将支持 TLS 1.2,自 2020 年以来,浏览器就要求使用 TLS 1.2。通过将 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
环境变量,将此功能临时恢复。此选项将在将来的版本中移除。
对库的少量更改
与往常一样,对库进行了各种小的更改和更新,这些更改和更新都牢记着 Go 1 的 兼容性承诺。
bufio
新方法 Writer.AvailableBuffer
返回一个空缓冲区,该缓冲区可能具有非空的容量,可用于类似追加的 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
方法提供无效点,则该方法现在将返回一个随机点。在将来的版本中,该行为可能会更改为显式恐慌。
crypto/tls
新方法 Conn.NetConn
允许访问底层 net.Conn
.
crypto/x509
Certificate.Verify
现在使用平台 API 来验证 macOS 和 iOS 上的证书有效性,前提是它在使用 nil
VerifyOpts.Roots
或使用从 SystemCertPool
返回的根池时被调用。
SystemCertPool
现在可在 Windows 上使用。
在 Windows、macOS 和 iOS 上,当由 SystemCertPool
返回的 CertPool
添加了额外的证书时,Certificate.Verify
将执行两次验证:一次使用平台验证器 API 和系统根,一次使用 Go 验证器和额外的根。平台验证器 API 返回的链将被优先考虑。
CertPool.Subjects
已弃用。在 Windows、macOS 和 iOS 上,由 SystemCertPool
返回的 CertPool
将返回一个池,该池不包括由 Subjects
返回的切片中的系统根,因为静态列表无法适当地表示平台策略,并且可能无法从平台 API 中获得。
在 Go 1.19 中可能会移除对使用依赖于 MD5 哈希(MD5WithRSA
)的签名算法签署证书的支持。
debug/dwarf
结构体 StructField
和 BasicType
现在都有一个 DataBitOffset
字段,该字段保存 DW_AT_data_bit_offset
属性的值(如果存在)。
debug/elf
添加了常量 R_PPC64_RELATIVE
。
debug/plan9obj
方法 File.Symbols 现在如果文件没有符号部分,则返回新的导出错误值 ErrNoSymbols。
embed
一个 go:embed
指令现在可以以 all:
开头,以包含名称以点或下划线开头的文件。
go/ast
根据提议 对 go/ast 和 go/token 的补充,以支持参数化函数和类型 ,对 go/ast
包进行了以下补充
- 节点
FuncType
和TypeSpec
有一个新的字段TypeParams
,用于保存类型参数(如果有)。 - 新的表达式节点
IndexListExpr
表示具有多个索引的索引表达式,用于具有多个显式类型参数的函数和类型实例化。
go/constant
新方法 Kind.String
返回接收器类型的可读名称。
go/token
新常量 TILDE
表示 ~
符号,根据提议 对 go/ast 和 go/token 的补充,以支持参数化函数和类型 。
go/types
新的字段 Config.GoVersion
设置了接受的 Go 语言版本。
根据提议 对 go/types 的补充,以支持类型参数 ,对 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
在 WebAssembly 目标上,Transport
中的 Dial
、DialContext
、DialTLS
和 DialTLSContext
方法字段现在将在指定时被正确使用,用于进行 HTTP 请求。
新的 Cookie.Valid
方法报告 cookie 是否有效。
新的 MaxBytesHandler
函数创建一个 Handler
,它使用 MaxBytesReader
包装其 ResponseWriter
和 Request.Body
。
当查找包含非 ASCII 字符的域名时,Unicode 到 ASCII 的转换现在根据 Unicode IDNA 兼容性处理 标准 (UTS #46) 中定义的非过渡处理来完成。对四种不同的字符进行了重新解释:ß、ς、零宽度连接符 U+200D 和零宽度非连接符 U+200C。非过渡处理与大多数应用程序和 Web 浏览器一致。
os/user
User.GroupIds
现在在 cgo 不可用时使用 Go 原生实现。
reflect
新的 Value.SetIterKey
和 Value.SetIterValue
方法使用映射迭代器作为源设置值。它们等效于 Value.Set(iter.Key())
和 Value.Set(iter.Value())
,但分配更少。
新的 Value.UnsafePointer
方法将值的值返回为 unsafe.Pointer
。这允许调用者从 Value.UnsafeAddr
和 Value.Pointer
迁移以消除在调用站点执行 uintptr 到 unsafe.Pointer 转换的需要(如 unsafe.Pointer 规则要求的那样)。
新的 MapIter.Reset
方法更改其接收器以迭代不同的映射。使用 MapIter.Reset
允许在许多映射上进行无分配迭代。
已向 Value
添加了许多方法(Value.CanInt
、Value.CanUint
、Value.CanFloat
、Value.CanComplex
),用于测试转换是否安全。
Value.FieldByIndexErr
已被添加,以避免在 Value.FieldByIndex
中通过空指针指向嵌入结构时发生的恐慌。
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
CPU 分析器现在在 Linux 上使用每线程计时器。这增加了配置文件可以观察到的最大 CPU 使用率,并减少了一些形式的偏差。
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
已为 Windows 引入新的函数 SyscallN
,允许使用任意数量的参数进行调用。因此,Syscall
、Syscall6
、Syscall9
、Syscall12
、Syscall15
和 Syscall18
被弃用,转而使用 SyscallN
。
SysProcAttr.Pdeathsig
现在在 FreeBSD 中受支持。
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
。