Go 1.17 版本说明

Go 1.17 简介

最新的 Go 版本 1.17 在 Go 1.16 发布六个月后发布。它的大部分变化都在工具链、运行时和库的实现中。和以往一样,该版本保持了 Go 1 兼容性承诺。我们预计几乎所有 Go 程序将继续像以前一样编译和运行。

语言更改

Go 1.17 包含对语言的三个小改进。

unsafe 包的增强是为了简化编写符合 unsafe.Pointer 安全规则 的代码,但规则保持不变。特别是,正确使用 unsafe.Pointer 的现有程序仍然有效,新程序在使用 unsafe.Addunsafe.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/amd64openbsd/arm64 端口)上,系统调用是通过 libc 进行的,而不是直接使用机器指令。在 Go 1.17 中,这也将在 OpenBSD 上的 32 位 x86 和 32 位 ARM 架构(openbsd/386openbsd/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 标志还绕过了模块校验和验证,如果您需要该功能,请使用 GOPRIVATEGONOSUMDB。有关详细信息,请参阅 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.modgo.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.modgo.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 接口的类型的 AsIsUnwrap 方法的调用,这些方法具有与 errors 包期望的签名不同的签名。errors.{As,Is,Unwrap} 函数期望此类方法分别实现 Is(error) boolAs(interface{}) boolUnwrap() errorerrors.{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/amd64darwin/amd64windows/amd64 端口)的 Linux、macOS 和 Windows 上启用。

此更改不会影响任何安全 Go 代码的功能,并且旨在对大多数汇编代码没有影响。它可能会影响在访问函数参数时违反 unsafe.Pointer 规则的代码,或依赖于涉及比较函数代码指针的未记录行为的代码。为了与现有汇编函数保持兼容,编译器生成适配器函数,用于在新的基于寄存器的调用约定和以前的基于堆栈的调用约定之间转换。这些适配器通常对用户来说是不可见的,除非在汇编代码中获取 Go 函数的地址或在 Go 代码中使用 reflect.ValueOf(fn).Pointer()unsafe.Pointer 获取汇编函数的地址,现在将返回适配器的地址。依赖于这些代码指针值的代码可能不再按预期工作。适配器还会在两种情况下导致非常小的性能开销:通过 func 值间接从 Go 调用汇编函数,以及从汇编调用 Go 函数。

运行时生成的堆栈跟踪格式(在发生未捕获的 panic 时打印,或者在调用 runtime.Stack 时打印)得到了改进。以前,函数参数根据内存布局以十六进制字的形式打印。现在,源代码中的每个参数都会单独打印,并用逗号分隔。聚合类型(结构、数组、字符串、切片、接口和复数)参数用大括号分隔。需要注意的是,仅存在于寄存器中且未存储到内存中的参数的值可能不准确。函数返回值(通常不准确)不再打印。

包含闭包的函数现在可以内联。此更改的一个影响是,具有闭包的函数可能会为函数内联的每个位置生成不同的闭包代码指针。Go 函数值不能直接比较,但此更改可能会发现代码中使用 reflectunsafe.Pointer 绕过此语言限制并通过代码指针比较函数的错误。

当链接器使用外部链接模式时(这是在链接使用 cgo 的程序时默认情况),并且链接器使用 -I 选项调用,该选项现在将作为 -Wl,--dynamic-linker 选项传递给外部链接器。

标准库

Cgo

runtime/cgo 包现在提供了一种新功能,允许将任何 Go 值转换为安全表示,该表示可以安全地用于在 C 和 Go 之间传递值。有关更多信息,请参阅 runtime/cgo.Handle

URL 查询解析

net/urlnet/http 包以前在 URL 查询中接受 ";"(分号)作为设置分隔符,除了 "&"(和号)之外。现在,具有非百分比编码分号的设置将被拒绝,并且 net/http 服务器将在请求 URL 中遇到分号时向 Server.ErrorLog 记录警告。

例如,在 Go 1.17 之前,URL example?a=1;b=2&c=3Query 方法将返回 map[a:[1] b:[2] c:[3]],而现在它返回 map[c:[3]]

在遇到这样的查询字符串时,URL.QueryRequest.FormValue 会忽略任何包含分号的设置,ParseQuery 会返回剩余的设置和错误,而 Request.ParseFormRequest.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.OpenRawWriter.CreateRawWriter.Copy 提供了对性能是主要关注点的用例的支持。

bufio

Writer.WriteRune 方法现在为负 rune 值写入替换字符 U+FFFD,就像它对其他无效 rune 一样。

bytes

Buffer.WriteRune 方法现在为负 rune 值写入替换字符 U+FFFD,就像它对其他无效 rune 一样。

compress/lzw

NewReader 函数保证返回新类型 Reader 的值,类似地,NewWriter 保证返回新类型 Writer 的值。这些新类型都实现了一个 Reset 方法(Reader.ResetWriter.Reset),允许重用 ReaderWriter

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.ContextCertificateRequestInfo.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 接口。

新的 NullInt16NullByte 结构体表示可能为 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

SourceNode 函数现在将 //go:build 行与 // +build 行同步。 如果文件只有 // +build 行,它们将被移动到文件中的适当位置,并且会添加匹配的 //go:build 行。 否则,将根据任何现有的 //go:build 行覆盖 // +build 行。 有关更多信息,请参阅 https://golang.ac.cn/design/draft-gobuild

go/parser

新的 SkipObjectResolution Mode 值指示解析器不要将标识符解析为其声明。 这可能会提高解析速度。

image

具体的图像类型(RGBAGray16 等)现在实现了一个新的 RGBA64Image 接口。 以前实现 draw.Image 的具体类型现在也实现了 draw.RGBA64Image,这是 image/draw 包中的一个新接口。

io/fs

新的 FileInfoToDirEntry 函数将 FileInfo 转换为 DirEntry

math

math 包现在定义了另外三个常量:MaxUintMaxIntMinInt。 对于 32 位系统,它们的值分别为 2^32 - 12^31 - 1-2^31。 对于 64 位系统,它们的值分别为 2^64 - 12^63 - 1-2^63

mime

在 Unix 系统上,MIME 类型表现在从本地系统的 共享 MIME 信息数据库 中读取(如果可用)。

mime/multipart

Part.FileName 现在将 filepath.Base 应用于返回值。 这减轻了在接受多部分消息的应用程序中潜在的路径遍历漏洞,例如调用 Request.FormFilenet/http 服务器。

net

新方法 IP.IsPrivate 报告一个地址是否根据 RFC 1918 是私有 IPv4 地址或根据 RFC 4193 是本地 IPv6 地址。

Go DNS 解析器现在在解析仅 IPv4 或仅 IPv6 网络的地址时只发送一个 DNS 查询,而不是查询两个地址族。

ErrClosed 哨兵错误和 ParseError 错误类型现在实现了 net.Error 接口。

ParseIPParseCIDR 函数现在拒绝包含前导零的十进制组件的 IPv4 地址。 这些组件始终被解释为十进制,但某些操作系统将它们视为八进制。 如果 Go 应用程序用于验证 IP 地址,然后以其原始形式与非 Go 应用程序一起使用,而这些应用程序将组件解释为八进制,则这种不匹配可能会导致安全问题。 通常,建议在验证后始终重新编码值,这将避免此类解析器错位问题。

net/http

net/http 包现在使用新的 (*tls.Conn).HandshakeContext,并在客户端或服务器中执行 TLS 握手时使用 Request 上下文。

Server ReadTimeoutWriteTimeout 字段设置为负值现在表示没有超时,而不是立即超时。

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.IsExportedMethod.IsExported 方法报告结构体字段或类型方法是否导出。 它们提供了一个更易读的替代方法来检查 PkgPath 是否为空。

新的 VisibleFields 函数返回结构体类型中的所有可见字段,包括匿名结构体成员内部的字段。

ArrayOf 函数现在在使用负长度调用时会引发 panic。

检查 Type.ConvertibleTo 方法不再足以保证对 Value.Convert 的调用不会引发 panic。 如果切片的长度小于 N,则在将 []T 转换为 *[N]T 时可能会引发 panic。 请参阅上面的 语言更改 部分。

Value.ConvertType.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 现在有 SwapCompareAndSwap 方法,它们提供额外的原子操作。

syscall

GetQueuedCompletionStatusPostQueuedCompletionStatus 函数现在已弃用。 这些函数具有不正确的签名,并且被 golang.org/x/sys/windows 包中的等效项取代。

在类 Unix 系统上,子进程的进程组现在是在信号被阻塞的情况下设置的。 这避免了在父进程位于后台进程组时向子进程发送 SIGTTOU

Windows 版本的 SysProcAttr 有两个新字段。AdditionalInheritedHandles 是一个要由新子进程继承的附加句柄列表。ParentProcess 允许指定新进程的父进程。

常量 MSG_CMSG_CLOEXEC 现在在 DragonFly 和所有 OpenBSD 系统上定义(它已经定义在某些 OpenBSD 系统和所有 FreeBSD、NetBSD 和 Linux 系统上)。

常量 SYS_WAIT6WEXITED 现在在 NetBSD 系统上定义(SYS_WAIT6 已经在 DragonFly 和 FreeBSD 系统上定义;WEXITED 已经在 Darwin、DragonFly、FreeBSD、Linux 和 Solaris 系统上定义)。

测试

添加了一个新的 测试标志 -shuffle,它控制测试和基准测试的执行顺序。

新的 T.SetenvB.Setenv 方法支持在测试或基准测试持续期间设置环境变量。

text/template/parse

新的 SkipFuncCheck Mode 值会更改模板解析器,使其不再验证函数是否已定义。

时间

Time 类型现在具有一个 GoString 方法,当使用 fmt 包中的 %#v 格式说明符打印时,该方法将返回更实用的时间值。

新的 Time.IsDST 方法可用于检查时间是否在其配置位置的夏令时。

新的 Time.UnixMilliTime.UnixMicro 方法分别返回自 1970 年 1 月 1 日 UTC 以来经过的毫秒数和微秒数。
新的 UnixMilliUnixMicro 函数返回与给定 Unix 时间相对应的本地 Time

该包现在接受逗号“,”作为解析和格式化时间时小数秒的分隔符。例如,以下时间布局现在被接受

新的常量 Layout 定义了参考时间。

unicode

IsIsGraphicIsLetterIsLowerIsMarkIsNumberIsPrintIsPunctIsSpaceIsSymbolIsUpper 函数现在对负运行值返回 false,就像它们对其他无效运行值那样。