Go 1.17 版本说明
Go 1.17 简介
最新的 Go 版本 1.17 在 Go 1.16 发布六个月后发布。它的大部分变化都在工具链、运行时和库的实现中。和以往一样,该版本保持了 Go 1 兼容性承诺。我们预计几乎所有 Go 程序将继续像以前一样编译和运行。
语言更改
Go 1.17 包含对语言的三个小改进。
-
从切片到数组指针的转换: 类型为
[]T
的表达式s
现在可以转换为数组指针类型*[N]T
。如果a
是这种转换的结果,则在范围内的对应索引引用相同的底层元素:&a[i] == &s[i]
,其中0 <= i < N
。如果len(s)
小于N
,则转换会引发恐慌。 -
unsafe.Add
:unsafe.Add(ptr, len)
将len
添加到ptr
并返回更新后的指针unsafe.Pointer(uintptr(ptr) + uintptr(len))
。 -
unsafe.Slice
: 对于类型为*T
的表达式ptr
,unsafe.Slice(ptr, len)
返回类型为[]T
的切片,其底层数组从ptr
开始,其长度和容量为len
。
对 unsafe
包的增强是为了简化编写符合 unsafe.Pointer
安全规则 的代码,但规则保持不变。特别是,正确使用 unsafe.Pointer
的现有程序仍然有效,新程序在使用 unsafe.Add
或 unsafe.Slice
时仍然必须遵循这些规则。
请注意,从切片到数组指针的新转换是类型转换在运行时可能引发恐慌的第一个案例。假设类型转换永远不会引发恐慌的分析工具应该更新以考虑这种可能性。
端口
Darwin
如 Go 1.16 版本说明中 宣布,Go 1.17 需要 macOS 10.13 High Sierra 或更高版本;对先前版本的支持已停止。
Windows
Go 1.17 添加了对 Windows 上 64 位 ARM 架构的支持(windows/arm64
端口)。此端口支持 cgo。
OpenBSD
OpenBSD 上的 64 位 MIPS 架构(openbsd/mips64
端口)现在支持 cgo。
在 Go 1.16 中,在 OpenBSD 上的 64 位 x86 和 64 位 ARM 架构(openbsd/amd64
和 openbsd/arm64
端口)上,系统调用是通过 libc
进行的,而不是直接使用机器指令。在 Go 1.17 中,这也将在 OpenBSD 上的 32 位 x86 和 32 位 ARM 架构(openbsd/386
和 openbsd/arm
端口)上完成。这确保了与 OpenBSD 6.9 及更高版本(要求通过 libc
进行系统调用以获得非静态 Go 二进制文件)的兼容性。
ARM64
Go 程序现在在所有操作系统上的 64 位 ARM 架构上维护堆栈帧指针。以前,堆栈帧指针仅在 Linux、macOS 和 iOS 上启用。
loong64 GOARCH 值保留
主 Go 编译器尚不支持 LoongArch 架构,但我们已保留了 GOARCH
值“loong64
”。这意味着命名为 *_loong64.go
的 Go 文件现在将 被 Go 工具忽略,除非正在使用该 GOARCH 值。
工具
Go 命令
go 1.17
模块中修剪的模块图
如果模块指定 go
1.17
或更高版本,则模块图仅包括其他 go
1.17
模块的直接依赖项,而不是它们的完整传递依赖项。(有关更多详细信息,请参阅 模块图修剪。)
为了使 go
命令能够使用修剪的模块图正确解析传递导入,每个模块的 go.mod
文件需要包含更多关于与该模块相关的传递依赖项的详细信息。如果模块在其 go.mod
文件中指定 go
1.17
或更高版本,则其 go.mod
文件现在包含对每个提供传递导入包的模块的显式 require
指令。(在以前的版本中,go.mod
文件通常只包含对直接导入包的显式要求。)
由于用于模块图修剪的扩展 go.mod
文件包含加载主模块中任何包的导入所需的所有依赖项,因此如果主模块指定 go
1.17
或更高版本,则 go
工具不再读取(甚至下载)依赖项的 go.mod
文件(如果它们不是完成请求的命令所必需的)。(请参阅 延迟加载。)
由于在扩展的 Go 1.17 go.mod
文件中,显式要求的数量可能要大得多,因此在 Go 1.17
模块中对间接依赖项的新添加的要求将保存在与包含直接依赖项的块分开的 require
块中。
为了方便升级到 Go 1.17 修剪的模块图,go
mod
tidy
子命令现在支持 -go
标志来设置或更改 go.mod
文件中的 go
版本。要将现有模块的 go.mod
文件转换为 Go 1.17,而不更改其依赖项的选择版本,请运行
go mod tidy -go=1.17
默认情况下,go
mod
tidy
将验证与主模块相关的依赖项的选择版本是否与先前 Go 版本(对于指定 go
1.17
的模块,为 Go 1.16)所使用的版本相同,并将保存该版本所需的 go.sum
条目,即使对于通常不需要的其他命令的依赖项也是如此。
-compat
标志允许覆盖该版本以支持更旧的(或仅更新的)版本,直到 go.mod
文件中的 go
指令指定的版本。要整理仅用于 Go 1.17 的 Go 1.17
模块,而不保存(或检查与)Go 1.16 的校验和
go mod tidy -compat=1.17
请注意,即使主模块使用 -compat=1.17
整理,从 Go 1.16
或更早版本的模块中require
该模块的用户仍然可以使用它,前提是这些包仅使用兼容的语言和库功能。
go
mod
graph
子命令也支持 -go
标志,这将导致它报告所指示的 Go 版本所看到的图形,并显示可能被修剪掉的其他依赖项。
模块弃用注释
模块作者可以通过在 go.mod
中添加 // Deprecated:
注释,然后标记新版本来弃用模块。go
get
现在会打印警告信息,如果在命令行上命名的包所需模块已弃用。go
list
-m
-u
打印所有依赖项的弃用信息(使用 -f
或 -json
显示完整消息)。go
命令认为不同的主要版本是不同的模块,因此此机制可用于,例如,为用户提供新主要版本的迁移说明。
go
get
go
get
-insecure
标志已弃用,已删除。要允许在获取依赖项时使用不安全的方案,请使用 GOINSECURE
环境变量。-insecure
标志还绕过了模块校验和验证,如果您需要该功能,请使用 GOPRIVATE
或 GONOSUMDB
。有关详细信息,请参阅 go
help
environment
。
go
get
在安装主模块之外的命令(没有 -d
标志)时会打印弃用警告。go
install
cmd@version
应改为用于安装特定版本的命令,使用 @latest
或 @v1.2.3
这样的后缀。在 Go 1.18 中,-d
标志将始终启用,go
get
将仅用于更改 go.mod
中的依赖项。
缺少 go
指令的 go.mod
文件
如果主模块的 go.mod
文件不包含 go
指令,并且 go
命令无法更新 go.mod
文件,则 go
命令现在假设 go 1.11
,而不是当前版本。(go
mod
init
已 从 Go 1.12 开始 自动添加 go
指令。)
如果模块依赖项缺少显式的 go.mod
文件,或者其 go.mod
文件不包含 go
指令,则 go
命令现在假设该依赖项为 go 1.16
,而不是当前版本。(在 GOPATH 模式下开发的依赖项可能缺少 go.mod
文件,并且 vendor/modules.txt
到目前为止从未记录依赖项的 go.mod
文件指示的 go
版本。)
vendor
内容
如果主模块指定 go
1.17
或更高版本,则 go
mod
vendor
现在使用其自身 go.mod
文件中每个供应商模块指示的 go
版本来注释 vendor/modules.txt
。注释的版本在从供应商源代码构建模块的包时使用。
如果主模块指定 go
1.17
或更高版本,go
mod
vendor
现在会省略 go.mod
和 go.sum
文件,这些文件用于供应商依赖项,否则可能会干扰 go
命令在 vendor
树中调用时识别正确模块根的能力。
密码提示
go
命令现在默认情况下会抑制使用 SSH 获取 Git 存储库时的 SSH 密码提示和 Git Credential Manager 提示,就像之前对其他 Git 密码提示一样。使用密码保护的 SSH 对私有 Git 存储库进行身份验证的用户可以配置 ssh-agent
以使 go
命令能够使用密码保护的 SSH 密钥。
go
mod
download
当 go
mod
download
在没有参数的情况下调用时,它将不再为下载的模块内容保存 go.sum
中的总和。它仍然可以对 go.mod
和 go.sum
进行必要的更改以加载构建列表。这与 Go 1.15 中的行为相同。要为所有模块保存总和,请使用 go
mod
download
all
。
//go:build
行
go
命令现在理解 //go:build
行,并优先于 // +build
行。新的语法使用布尔表达式,就像 Go 一样,并且应该更不容易出错。从本版本开始,新语法得到完全支持,所有 Go 文件都应更新为具有相同的含义的两种形式。为了帮助迁移,gofmt
现在自动同步这两种形式。有关语法和迁移计划的更多详细信息,请参阅 https://golang.ac.cn/design/draft-gobuild。
go
run
go
run
现在接受带有版本后缀的参数(例如,go
run
example.com/[email protected]
)。这会导致 go
run
以模块感知模式构建和运行包,忽略当前目录或任何父目录(如果有)中的 go.mod
文件。这对于在不安装可执行文件或不更改当前模块的依赖项的情况下运行可执行文件很有用。
Gofmt
gofmt
(以及 go
fmt
)现在同步 //go:build
行和 // +build
行。如果文件只有 // +build
行,它们将被移动到文件中的适当位置,并且会添加匹配的 //go:build
行。否则,将根据任何现有的 //go:build
行覆盖 // +build
行。有关更多信息,请参阅 https://golang.ac.cn/design/draft-gobuild。
Vet
对不匹配的 //go:build
和 // +build
行发出新警告
vet
工具现在验证 //go:build
和 // +build
行是否位于文件的正确部分并彼此同步。如果它们没有,gofmt
可用于修复它们。有关更多信息,请参阅 https://golang.ac.cn/design/draft-gobuild。
对在未缓冲的通道上调用 signal.Notify
发出新警告
vet 工具现在警告对 signal.Notify 的调用,其中传入信号被发送到未缓冲的通道。使用未缓冲的通道可能会错过发送到它们上的信号,因为 signal.Notify
在发送到通道时不会阻塞。例如
c := make(chan os.Signal)
// signals are sent on c before the channel is read from.
// This signal may be dropped as c is unbuffered.
signal.Notify(c, os.Interrupt)
signal.Notify
的用户应使用具有足够缓冲空间的通道来跟上预期的信号速率。
对 Is、As 和 Unwrap 方法发出新警告
vet 工具现在警告对实现 error
接口的类型的 As
、Is
或 Unwrap
方法的调用,这些方法具有与 errors
包期望的签名不同的签名。errors.{As,Is,Unwrap}
函数期望此类方法分别实现 Is(error)
bool
、As(interface{})
bool
或 Unwrap()
error
。errors.{As,Is,Unwrap}
函数将忽略具有相同名称但不同签名的函数。例如
type MyError struct { hint string }
func (m MyError) Error() string { ... } // MyError implements error.
func (MyError) Is(target interface{}) bool { ... } // target is interface{} instead of error.
func Foo() bool {
x, y := MyError{"A"}, MyError{"B"}
return errors.Is(x, y) // returns false as x != y and MyError does not have an `Is(error) bool` function.
}
Cover
cover
工具现在使用来自 golang.org/x/tools/cover
的优化解析器,这在解析大型覆盖配置文件时可能会显着更快。
编译器
Go 1.17 实现了一种新的使用寄存器而不是堆栈传递函数参数和结果的方法。对一组代表性的 Go 包和程序的基准测试表明性能提高了大约 5%,并且二进制文件大小通常减少了大约 2%。目前,此功能已在 64 位 x86 架构(linux/amd64
、darwin/amd64
和 windows/amd64
端口)的 Linux、macOS 和 Windows 上启用。
此更改不会影响任何安全 Go 代码的功能,并且旨在对大多数汇编代码没有影响。它可能会影响在访问函数参数时违反 unsafe.Pointer
规则的代码,或依赖于涉及比较函数代码指针的未记录行为的代码。为了与现有汇编函数保持兼容,编译器生成适配器函数,用于在新的基于寄存器的调用约定和以前的基于堆栈的调用约定之间转换。这些适配器通常对用户来说是不可见的,除非在汇编代码中获取 Go 函数的地址或在 Go 代码中使用 reflect.ValueOf(fn).Pointer()
或 unsafe.Pointer
获取汇编函数的地址,现在将返回适配器的地址。依赖于这些代码指针值的代码可能不再按预期工作。适配器还会在两种情况下导致非常小的性能开销:通过 func
值间接从 Go 调用汇编函数,以及从汇编调用 Go 函数。
运行时生成的堆栈跟踪格式(在发生未捕获的 panic 时打印,或者在调用 runtime.Stack
时打印)得到了改进。以前,函数参数根据内存布局以十六进制字的形式打印。现在,源代码中的每个参数都会单独打印,并用逗号分隔。聚合类型(结构、数组、字符串、切片、接口和复数)参数用大括号分隔。需要注意的是,仅存在于寄存器中且未存储到内存中的参数的值可能不准确。函数返回值(通常不准确)不再打印。
包含闭包的函数现在可以内联。此更改的一个影响是,具有闭包的函数可能会为函数内联的每个位置生成不同的闭包代码指针。Go 函数值不能直接比较,但此更改可能会发现代码中使用 reflect
或 unsafe.Pointer
绕过此语言限制并通过代码指针比较函数的错误。
链接器
当链接器使用外部链接模式时(这是在链接使用 cgo 的程序时默认情况),并且链接器使用 -I
选项调用,该选项现在将作为 -Wl,--dynamic-linker
选项传递给外部链接器。
标准库
Cgo
runtime/cgo 包现在提供了一种新功能,允许将任何 Go 值转换为安全表示,该表示可以安全地用于在 C 和 Go 之间传递值。有关更多信息,请参阅 runtime/cgo.Handle。
URL 查询解析
net/url
和 net/http
包以前在 URL 查询中接受 ";"
(分号)作为设置分隔符,除了 "&"
(和号)之外。现在,具有非百分比编码分号的设置将被拒绝,并且 net/http
服务器将在请求 URL 中遇到分号时向 Server.ErrorLog
记录警告。
例如,在 Go 1.17 之前,URL example?a=1;b=2&c=3
的 Query
方法将返回 map[a:[1] b:[2] c:[3]]
,而现在它返回 map[c:[3]]
。
在遇到这样的查询字符串时,URL.Query
和 Request.FormValue
会忽略任何包含分号的设置,ParseQuery
会返回剩余的设置和错误,而 Request.ParseForm
和 Request.ParseMultipartForm
会返回错误,但仍会根据剩余的设置设置 Request
字段。
net/http
用户可以使用新的 AllowQuerySemicolons
处理程序包装器恢复原始行为。这也将抑制 ErrorLog
警告。请注意,接受分号作为查询分隔符可能会导致安全问题,如果不同的系统对缓存键的解释不同。有关更多信息,请参阅 问题 25192。
TLS 严格 ALPN
当设置了 Config.NextProtos
时,服务器现在强制在配置的协议和客户端(如果有)通告的 ALPN 协议之间存在重叠。如果没有相互支持的协议,连接将使用 no_application_protocol
警告关闭,如 RFC 7301 所要求。这有助于缓解 ALPACA 跨协议攻击。
作为一个例外,当服务器的 Config.NextProtos
中包含值 "h2"
时,将允许 HTTP/1.1 客户端连接,就像它们不支持 ALPN 一样。有关更多信息,请参阅 问题 46310。
对库的细微更改
与往常一样,对库进行了各种细微的更改和更新,并且始终牢记 Go 1 的 兼容性承诺。
archive/zip
新的方法 File.OpenRaw
、Writer.CreateRaw
、Writer.Copy
提供了对性能是主要关注点的用例的支持。
bufio
Writer.WriteRune
方法现在为负 rune 值写入替换字符 U+FFFD,就像它对其他无效 rune 一样。
bytes
Buffer.WriteRune
方法现在为负 rune 值写入替换字符 U+FFFD,就像它对其他无效 rune 一样。
compress/lzw
NewReader
函数保证返回新类型 Reader
的值,类似地,NewWriter
保证返回新类型 Writer
的值。这些新类型都实现了一个 Reset
方法(Reader.Reset
、Writer.Reset
),允许重用 Reader
或 Writer
。
crypto/ed25519
crypto/ed25519
包已重写,所有操作在 amd64 和 arm64 上的速度现在大约快了一倍。可观察到的行为没有其他变化。
crypto/elliptic
CurveParams
方法现在会自动为已知的曲线(P-224、P-256 和 P-521)调用更快的更安全的专用实现(如果可用)。请注意,这是一个尽力而为的方法,应用程序应避免使用通用的、非恒定时间的 CurveParams
方法,而是使用专用的 Curve
实现,例如 P256
。
P521
曲线实现已使用由 fiat-crypto 项目 生成的代码重写,该代码基于对算术运算的正式验证模型。它现在是恒定时间的,并且在 amd64 和 arm64 上快了三倍。可观察到的行为没有其他变化。
crypto/rand
crypto/rand
包现在在 macOS 上使用 getentropy
系统调用,在 Solaris、Illumos 和 DragonFlyBSD 上使用 getrandom
系统调用。
crypto/tls
新的 Conn.HandshakeContext
方法允许用户控制正在进行的 TLS 握手取消。 提供的上下文可以通过新的 ClientHelloInfo.Context
和 CertificateRequestInfo.Context
方法从各种回调中访问。 握手完成后取消上下文无效。
密码套件排序现在完全由 crypto/tls
包处理。 当前,密码套件是根据其安全性、性能和硬件支持排序的,同时考虑了本地和对等方的硬件。 Config.CipherSuites
字段的顺序现在被忽略,Config.PreferServerCipherSuites
字段也是如此。 请注意,Config.CipherSuites
仍然允许应用程序选择要启用的 TLS 1.0-1.2 密码套件。
3DES 密码套件已移至 InsecureCipherSuites
,因为 存在基本块大小相关的弱点。 由于上述密码套件排序更改,它们默认情况下仍然启用,但仅作为最后手段。
从下一个版本,Go 1.18 开始,crypto/tls
客户端的 Config.MinVersion
将默认设置为 TLS 1.2,默认情况下禁用 TLS 1.0 和 TLS 1.1。 应用程序可以通过显式设置 Config.MinVersion
来覆盖此更改。 这不会影响 crypto/tls
服务器。
crypto/x509
CreateCertificate
现在会在提供的私钥与父级公钥(如果有)不匹配时返回错误。 生成的证书将无法验证。
临时 GODEBUG=x509ignoreCN=0
标志已删除。
ParseCertificate
已经重写,现在消耗的资源减少了约 70%。 处理 WebPKI 证书时的可观察行为没有其他变化,除了错误消息。
在 BSD 系统上,现在将搜索 /etc/ssl/certs
以查找受信任的根证书。 这为 FreeBSD 12.2+ 中的新的系统受信任证书存储添加了支持。
从下一个版本,Go 1.18 开始,crypto/x509
将拒绝使用 SHA-1 哈希函数签名的证书。 这不适用于自签名根证书。 针对 SHA-1 的实际攻击 已于 2017 年得到证明,并且自 2015 年以来,公开信任的证书颁发机构没有颁发 SHA-1 证书。
database/sql
DB.Close
方法现在会关闭 connector
字段,如果该字段中的类型实现了 io.Closer
接口。
新的 NullInt16
和 NullByte
结构体表示可能为 null 的 int16 和字节值。 这些可以用作 Scan
方法的目标,类似于 NullString。
debug/elf
已添加 SHT_MIPS_ABIFLAGS
常量。
encoding/binary
binary.Uvarint
将在读取 10 字节
后停止读取,以避免浪费计算。 如果需要超过 10 字节
,则返回的字节数为 -11
。
以前的 Go 版本在读取编码不正确的 varints 时可能会返回更大的负数计数。
encoding/csv
新的 Reader.FieldPos
方法返回与最近由 Read
返回的记录中给定字段的开头相对应的行和列。
encoding/xml
当注释出现在 Directive
中时,它现在将被替换为空格,而不是完全省略。
具有前导、尾随或多个冒号的无效元素或属性名称现在将以未修改的方式存储到 Name.Local
字段中。
flag
如果指定了无效名称,则标志声明现在会引发 panic。
go/build
新的 Context.ToolTags
字段包含适用于当前 Go 工具链配置的构建标签。
go/format
Source
和 Node
函数现在将 //go:build
行与 // +build
行同步。 如果文件只有 // +build
行,它们将被移动到文件中的适当位置,并且会添加匹配的 //go:build
行。 否则,将根据任何现有的 //go:build
行覆盖 // +build
行。 有关更多信息,请参阅 https://golang.ac.cn/design/draft-gobuild。
go/parser
新的 SkipObjectResolution
Mode
值指示解析器不要将标识符解析为其声明。 这可能会提高解析速度。
image
具体的图像类型(RGBA
、Gray16
等)现在实现了一个新的 RGBA64Image
接口。 以前实现 draw.Image
的具体类型现在也实现了 draw.RGBA64Image
,这是 image/draw
包中的一个新接口。
io/fs
新的 FileInfoToDirEntry
函数将 FileInfo
转换为 DirEntry
。
math
math 包现在定义了另外三个常量:MaxUint
、MaxInt
和 MinInt
。 对于 32 位系统,它们的值分别为 2^32 - 1
、2^31 - 1
和 -2^31
。 对于 64 位系统,它们的值分别为 2^64 - 1
、2^63 - 1
和 -2^63
。
mime
在 Unix 系统上,MIME 类型表现在从本地系统的 共享 MIME 信息数据库 中读取(如果可用)。
mime/multipart
Part.FileName
现在将 filepath.Base
应用于返回值。 这减轻了在接受多部分消息的应用程序中潜在的路径遍历漏洞,例如调用 Request.FormFile
的 net/http
服务器。
net
新方法 IP.IsPrivate
报告一个地址是否根据 RFC 1918 是私有 IPv4 地址或根据 RFC 4193 是本地 IPv6 地址。
Go DNS 解析器现在在解析仅 IPv4 或仅 IPv6 网络的地址时只发送一个 DNS 查询,而不是查询两个地址族。
ErrClosed
哨兵错误和 ParseError
错误类型现在实现了 net.Error
接口。
ParseIP
和 ParseCIDR
函数现在拒绝包含前导零的十进制组件的 IPv4 地址。 这些组件始终被解释为十进制,但某些操作系统将它们视为八进制。 如果 Go 应用程序用于验证 IP 地址,然后以其原始形式与非 Go 应用程序一起使用,而这些应用程序将组件解释为八进制,则这种不匹配可能会导致安全问题。 通常,建议在验证后始终重新编码值,这将避免此类解析器错位问题。
net/http
net/http
包现在使用新的 (*tls.Conn).HandshakeContext
,并在客户端或服务器中执行 TLS 握手时使用 Request
上下文。
将 Server
ReadTimeout
或 WriteTimeout
字段设置为负值现在表示没有超时,而不是立即超时。
ReadRequest
函数现在在请求具有多个 Host 标头时返回错误。
在生成对已清理版本的 URL 的重定向时,ServeMux
现在始终在 Location
标头中使用相对 URL。 以前它会回显请求的完整 URL,如果可以使客户端发送绝对请求 URL,则可能导致意外的重定向。
在解释由 net/http
处理的某些 HTTP 标头时,现在会忽略或拒绝非 ASCII 字符。
如果 Request.ParseForm
在被 Request.ParseMultipartForm
调用时返回错误,则后者现在会继续填充 Request.MultipartForm
然后再返回它。
net/http/httptest
ResponseRecorder.WriteHeader
现在会在提供的代码不是有效的三位数 HTTP 状态代码时引发 panic。 这与 net/http
包中的 ResponseWriter
实现的行为相匹配。
net/url
新方法 Values.Has
报告查询参数是否已设置。
os
File.WriteString
方法已优化为不复制输入字符串。
reflect
新的 Value.CanConvert
方法报告一个值是否可以转换为一个类型。 这可用于在将切片转换为数组指针类型时避免 panic,如果切片过短。 以前,对于这种情况,使用 Type.ConvertibleTo
就足够了,但是新允许的从切片到数组指针类型的转换即使类型可转换也会引发 panic。
新的 StructField.IsExported
和 Method.IsExported
方法报告结构体字段或类型方法是否导出。 它们提供了一个更易读的替代方法来检查 PkgPath
是否为空。
新的 VisibleFields
函数返回结构体类型中的所有可见字段,包括匿名结构体成员内部的字段。
ArrayOf
函数现在在使用负长度调用时会引发 panic。
检查 Type.ConvertibleTo
方法不再足以保证对 Value.Convert
的调用不会引发 panic。 如果切片的长度小于 N,则在将 []T
转换为 *[N]T
时可能会引发 panic。 请参阅上面的 语言更改 部分。
Value.Convert
和 Type.ConvertibleTo
方法已修复,不再将不同包中具有相同名称的类型视为相同,以匹配语言允许的内容。
runtime/metrics
添加了新的指标,用于跟踪分配和释放的总字节数和对象数。 还添加了一个新的指标,用于跟踪 goroutine 调度延迟的分布。
runtime/pprof
块配置文件不再偏向于偏爱不频繁的长事件而不是频繁的短事件。
strconv
strconv
包现在使用 Ulf Adams 的 Ryū 算法来格式化浮点数。 此算法提高了大多数输入的性能,并且在最坏情况下的输入上快了 99% 以上。
新的 QuotedPrefix
函数返回输入开头的引号字符串(如 Unquote
理解的那样)。
strings
Builder.WriteRune
方法现在为负的 rune 值写入替换字符 U+FFFD,就像它对其他无效的 rune 所做的那样。
sync/atomic
atomic.Value
现在有 Swap
和 CompareAndSwap
方法,它们提供额外的原子操作。
syscall
GetQueuedCompletionStatus
和 PostQueuedCompletionStatus
函数现在已弃用。 这些函数具有不正确的签名,并且被 golang.org/x/sys/windows
包中的等效项取代。
在类 Unix 系统上,子进程的进程组现在是在信号被阻塞的情况下设置的。 这避免了在父进程位于后台进程组时向子进程发送 SIGTTOU
。
Windows 版本的 SysProcAttr
有两个新字段。AdditionalInheritedHandles
是一个要由新子进程继承的附加句柄列表。ParentProcess
允许指定新进程的父进程。
常量 MSG_CMSG_CLOEXEC
现在在 DragonFly 和所有 OpenBSD 系统上定义(它已经定义在某些 OpenBSD 系统和所有 FreeBSD、NetBSD 和 Linux 系统上)。
常量 SYS_WAIT6
和 WEXITED
现在在 NetBSD 系统上定义(SYS_WAIT6
已经在 DragonFly 和 FreeBSD 系统上定义;WEXITED
已经在 Darwin、DragonFly、FreeBSD、Linux 和 Solaris 系统上定义)。
测试
添加了一个新的 测试标志 -shuffle
,它控制测试和基准测试的执行顺序。
新的 T.Setenv
和 B.Setenv
方法支持在测试或基准测试持续期间设置环境变量。
text/template/parse
新的 SkipFuncCheck
Mode
值会更改模板解析器,使其不再验证函数是否已定义。
时间
Time
类型现在具有一个 GoString
方法,当使用 fmt
包中的 %#v
格式说明符打印时,该方法将返回更实用的时间值。
新的 Time.IsDST
方法可用于检查时间是否在其配置位置的夏令时。
新的 Time.UnixMilli
和 Time.UnixMicro
方法分别返回自 1970 年 1 月 1 日 UTC 以来经过的毫秒数和微秒数。
新的 UnixMilli
和 UnixMicro
函数返回与给定 Unix 时间相对应的本地 Time
。
该包现在接受逗号“,”作为解析和格式化时间时小数秒的分隔符。例如,以下时间布局现在被接受
- 2006-01-02 15:04:05,999999999 -0700 MST
- Mon Jan _2 15:04:05,000000 2006
- Monday, January 2 15:04:05,000 2006
新的常量 Layout
定义了参考时间。
unicode
Is
、
、IsGraphic
、IsLetter
、IsLower
、IsMark
、IsNumber
、IsPrint
、IsPunct
、IsSpace
和 IsSymbol
函数现在对负运行值返回 IsUpper
false
,就像它们对其他无效运行值那样。