Go 1.5 发行说明
Go 1.5 简介
最新的 Go 版本 1.5 是一个重要的版本,包含了对实现进行的主要架构更改。尽管如此,我们预计几乎所有 Go 程序都能像以前一样继续编译和运行,因为该版本仍然遵守 Go 1 的兼容性承诺。
实现方面最大的发展是:
- 编译器和运行时现在完全用 Go 编写(只有少量汇编)。C 不再参与实现,因此曾经用于构建分发包的 C 编译器也已移除。
- 垃圾收集器现在是并发的,并且通过尽可能与其他 goroutine 并行运行,显著降低了暂停时间。
- 默认情况下,Go 程序运行时的
GOMAXPROCS
设置为可用核心数;在之前的版本中,它默认为 1。 - 现在所有仓库都支持内部包,而不仅仅是 Go 核心。
go
命令现在提供对外部依赖项“vendoring”(版本管理)的实验性支持。- 新的
go tool trace
命令支持程序执行的细粒度跟踪。 - 一个新的
go doc
命令(与godoc
不同)专为命令行使用而定制。
这些以及对实现和工具的其他一些更改将在下面讨论。
该版本还包含一个关于 map 字面量的小语言更改。
最后,发布时间偏离了通常的六个月间隔,这既是为了为这个主要版本提供更多的准备时间,也是为了之后调整发布时间表,使发布日期更方便。
语言变化
Map 字面量
由于疏忽,允许从切片字面量中省略元素类型的规则未应用于 map 键。这已在 Go 1.5 中得到纠正。一个例子可以说明这一点。从 Go 1.5 开始,这个 map 字面量,
m := map[Point]string{
Point{29.935523, 52.891566}: "Persepolis",
Point{-25.352594, 131.034361}: "Uluru",
Point{37.422455, -122.084306}: "Googleplex",
}
可以写成如下形式,无需显式列出 Point
类型
m := map[Point]string{
{29.935523, 52.891566}: "Persepolis",
{-25.352594, 131.034361}: "Uluru",
{37.422455, -122.084306}: "Googleplex",
}
实现
不再有 C
编译器和运行时现在用 Go 和汇编语言实现,没有 C。树中仅剩的 C 源代码与测试或 cgo
相关。在 1.4 及更早版本中,树中有一个 C 编译器。它用于构建运行时;部分原因需要一个自定义编译器来确保 C 代码与 goroutine 的堆栈管理一起工作。由于运行时现在在 Go 中,因此不再需要此 C 编译器,并且它已被移除。消除 C 的过程细节在其他地方讨论。
从 C 语言的转换是在为这项工作创建的自定义工具的帮助下完成的。最重要的是,编译器实际上是通过将 C 代码自动翻译成 Go 来移动的。它实际上是相同程序的另一种语言版本。它不是编译器的新实现,因此我们预计此过程不会引入新的编译器错误。此过程的概述可在此演示文稿的幻灯片中找到。
编译器和工具
独立于 Go 语言的迁移,但受其鼓励,工具的名称已更改。旧名称 6g
、8g
等已移除;现在只有一个二进制文件,可作为 go
tool
compile
访问,它将 Go 源代码编译成适合由 $GOARCH
和 $GOOS
指定的架构和操作系统的二进制文件。类似地,现在有一个链接器(go
tool
link
)和一个汇编器(go
tool
asm
)。链接器是从旧的 C 实现自动翻译的,但汇编器是下面将更详细讨论的新原生 Go 实现。
类似于放弃了 6g
、8g
等名称,编译器和汇编器的输出现在给定一个普通的 .o
后缀,而不是 .8
、.6
等。
垃圾收集器
垃圾收集器已在 1.5 中重新设计,作为设计文档中概述的开发的一部分。通过高级算法、更好的收集器调度以及更多并行收集用户程序,预期的延迟比以前版本的收集器低得多。收集器的“停止世界”阶段几乎总是低于 10 毫秒,通常远低于此。
对于受益于低延迟的系统,例如对用户响应的网站,新收集器预期的延迟降低可能很重要。
新收集器的详细信息已在 GopherCon 2015 的演讲中提出。
运行时
在 Go 1.5 中,goroutine 的调度顺序已更改。调度器的属性从未由语言定义,但依赖于调度顺序的程序可能会因此次更改而中断。我们已经看到一些(错误的)程序受到此更改的影响。如果您的程序隐式依赖于调度顺序,则需要更新它们。
另一个可能导致中断的更改是,运行时现在将默认同时运行的线程数(由 GOMAXPROCS
定义)设置为 CPU 上可用的核心数。在以前的版本中,默认值为 1。不期望使用多个核心运行的程序可能会意外中断。它们可以通过删除限制或显式设置 GOMAXPROCS
来更新。有关此更改的更详细讨论,请参阅设计文档。
构建
既然 Go 编译器和运行时是用 Go 实现的,就必须有一个 Go 编译器才能从源代码编译发行版。因此,要构建 Go 核心,必须已经有一个工作的 Go 发行版。(不从事核心工作的 Go 程序员不受此更改的影响。)任何 Go 1.4 或更高版本的发行版(包括 gccgo
)都可以。有关详细信息,请参阅设计文档。
移植
主要由于业界从 32 位 x86 架构转向,1.5 中提供的二进制下载集有所减少。OS X 操作系统的发行版仅提供给 amd64
架构,而不是 386
。同样,Snow Leopard(Apple OS X 10.6)的端口仍然有效,但不再作为下载发布或维护,因为 Apple 不再维护该版本的操作系统。此外,dragonfly/386
端口根本不再受支持,因为 DragonflyBSD 本身不再支持 32 位 386 架构。
但是,有几个新的端口可以从源代码构建。其中包括 darwin/arm
和 darwin/arm64
。新的 linux/arm64
端口大部分已到位,但 cgo
仅支持使用外部链接。
ppc64
和 ppc64le
(64 位 PowerPC,大端和小端)也作为实验提供。这两个端口都支持 cgo
,但仅支持内部链接。
在 FreeBSD 上,Go 1.5 需要 FreeBSD 8-STABLE+,因为其新使用了 SYSCALL
指令。
在 NaCl 上,Go 1.5 需要 SDK 版本 pepper-41。由于从 NaCl 运行时移除了 sRPC 子系统,后续 pepper 版本不兼容。
在 Darwin 上,可以使用 ios
构建标签禁用系统 X.509 证书接口。
Solaris 端口现在完全支持 cgo 和软件包net
和crypto/x509
,以及许多其他修复和改进。
工具
翻译
作为从树中消除 C 的过程的一部分,编译器和链接器从 C 翻译为 Go。这是一个真正的(机器辅助的)翻译,因此新程序本质上是旧程序的翻译版本,而不是带有新错误的新程序。我们相信翻译过程几乎没有引入任何新错误,事实上还发现了许多以前未知的错误,现已修复。
但是,汇编器是一个新程序;它将在下面描述。
重命名
编译器(6g
、8g
等)、汇编器(6a
、8a
等)和链接器(6l
、8l
等)的程序套件已分别整合为一个工具,该工具由环境变量 GOOS
和 GOARCH
配置。旧名称已消失;新工具通过 go
tool
机制作为 go tool compile
、go tool asm
和 go tool link
提供。此外,用于中间目标文件的文件后缀 .6
、.8
等也已消失;现在它们只是普通的 .o
文件。
例如,要直接使用工具(而不是通过 go build
)在 amd64 上为 Darwin 构建和链接程序,可以运行
$ export GOOS=darwin GOARCH=amd64
$ go tool compile program.go
$ go tool link program.o
移动
由于 go/types
包现在已移入主仓库(见下文),vet
和 cover
工具也已移动。它们不再在外部 golang.org/x/tools
仓库中维护,尽管(已弃用的)源代码仍保留在那里以与旧版本兼容。
编译器
如上所述,Go 1.5 中的编译器是一个从旧 C 源代码翻译而来的单个 Go 程序,它取代了 6g
、8g
等。其目标由环境变量 GOOS
和 GOARCH
配置。
1.5 编译器与旧编译器基本等效,但一些内部细节已更改。一个重要的变化是常量评估现在使用 math/big
包,而不是自定义(且测试较少)的高精度算术实现。我们预计这不会影响结果。
仅对于 amd64 架构,编译器有一个新选项 -dynlink
,它通过支持引用外部共享库中定义的 Go 符号来协助动态链接。
汇编器
与编译器和链接器一样,Go 1.5 中的汇编器是一个替换汇编器套件(6a
、8a
等)的单一程序,环境变量 GOARCH
和 GOOS
配置架构和操作系统。与其他程序不同,汇编器是一个完全用 Go 编写的新程序。
新汇编器与以前的汇编器几乎兼容,但有一些更改可能会影响某些汇编源代码文件。有关这些更改的更具体信息,请参阅更新的汇编器指南。总而言之
首先,用于常量的表达式评估略有不同。它现在使用无符号 64 位算术,运算符(+
、-
、<<
等)的优先级来自 Go,而不是 C。我们预计这些更改会影响极少数程序,但可能需要手动验证。
也许更重要的是,在 SP
或 PC
只是编号寄存器的别名(例如 ARM 上堆栈指针的 R13
和硬件程序计数器的 R15
)的机器上,引用不包含符号的此类寄存器现在是非法的。例如,SP
和 4(SP)
是非法的,但 sym+4(SP)
是可以的。在此类机器上,要引用硬件寄存器,请使用其真实的 R
名称。
一个小的变化是,一些旧汇编器允许使用以下表示法
constant=value
定义一个命名常量。由于使用传统的类似 C 的 #define
表示法(仍然受支持,汇编器包含一个简化的 C 预处理器实现)总是可以做到这一点,因此该功能已删除。
链接器
Go 1.5 中的链接器现在是一个 Go 程序,它取代了 6l
、8l
等。其操作系统和指令集由环境变量 GOOS
和 GOARCH
指定。
还有其他一些变化。最重要的是增加了 -buildmode
选项,该选项扩展了链接样式;它现在支持构建共享库和允许其他语言调用 Go 库等情况。其中一些已在设计文档中概述。有关可用构建模式及其用法的列表,请运行
$ go help buildmode
另一个小的变化是链接器不再在 Windows 可执行文件的头中记录构建时间戳。此外,虽然这可能会修复,但 Windows cgo 可执行文件缺少一些 DWARF 信息。
最后,-X
标志,它接受两个参数,例如
-X importpath.name value
现在也接受更常见的 Go 标志样式,它带有一个单独的参数,该参数本身是一个 name=value
对
-X importpath.name=value
虽然旧语法仍然有效,但建议将脚本等中此标志的使用更新为新形式。
Go 命令
go
命令的基本操作没有改变,但有许多值得注意的更改。
之前的版本引入了通过 go
命令无法导入包内部目录的概念。在 1.4 中,它通过在核心仓库中引入一些内部元素进行了测试。正如设计文档中建议的那样,该更改现在已可用于所有仓库。规则在设计文档中解释,但总而言之,位于或包含在名为 internal
的目录中的任何包都可以由根植于同一子树中的包导入。现有包中包含名为 internal
的目录元素可能会因此次更改而意外中断,这就是在上次发布时宣传的原因。
包处理方式的另一个变化是实验性地增加了对“vendoring”的支持。有关详细信息,请参阅go
命令和设计文档的文档。
还有一些小改动。请阅读文档以获取完整详细信息。
- SWIG 支持已更新,现在
.swig
和.swigcxx
需要 SWIG 3.0.6 或更高版本。 - 如果存在,
install
子命令现在会删除build
子命令在源目录中创建的二进制文件,以避免树中存在两个二进制文件的问题。 std
(标准库)通配符包名现在排除命令。新的cmd
通配符覆盖命令。- 新的
-asmflags
构建选项设置要传递给汇编器的标志。但是,-ccflags
构建选项已删除;它特定于旧的、现已删除的 C 编译器。 - 新的
-buildmode
构建选项设置构建模式,如上所述。 - 新的
-pkgdir
构建选项设置已安装包存档的位置,以帮助隔离自定义构建。 - 新的
-toolexec
构建选项允许替换不同的命令来调用编译器等。这充当go tool
的自定义替换。 test
子命令现在有一个-count
标志,用于指定每个测试和基准运行多少次。testing
包通过-test.count
标志在此处完成工作。generate
子命令有几个新功能。-run
选项指定一个正则表达式来选择要执行的指令;这在 1.4 中被提出但从未实现。执行模式现在可以访问两个新的环境变量:$GOLINE
返回指令的源行号,$DOLLAR
扩展为美元符号。get
子命令现在有一个-insecure
标志,如果从不安全的仓库(即不加密连接的仓库)获取,则必须启用该标志。
Go vet 命令
go tool vet
命令现在对结构体标签进行更彻底的验证。
跟踪命令
Go 程序现在有一个用于动态执行跟踪的新工具。其用法类似于测试覆盖工具的工作方式。跟踪的生成集成到 go test
中,然后单独执行跟踪工具本身来分析结果
$ go test -trace=trace.out path/to/package
$ go tool trace [flags] pkg.test trace.out
这些标志允许在浏览器窗口中显示输出。有关详细信息,请运行 go tool trace -help
。GopherCon 2015 的此演讲中也有关于跟踪设施的描述。
Go doc 命令
几个版本前,go doc
命令因不必要而被删除。总是可以运行“godoc .
”代替。1.5 版本引入了一个新的go doc
命令,它比 godoc
具有更方便的命令行界面。它专为命令行使用而设计,并根据调用为包或其元素提供更紧凑和专注的文档呈现。它还提供不区分大小写的匹配和显示未导出符号文档的支持。有关详细信息,请运行“go help doc
”。
Cgo
解析 #cgo
行时,调用 ${SRCDIR}
现在会扩展为源目录的路径。这允许将涉及相对于源代码目录的文件路径的选项传递给编译器和链接器。如果没有扩展,当当前工作目录更改时,路径将无效。
Solaris 现在完全支持 cgo。
在 Windows 上,cgo 现在默认使用外部链接。
当 C 结构体以零大小字段结束,但结构体本身不是零大小时,Go 代码不再能引用该零大小字段。任何此类引用都必须重写。
性能
一如既往,这些变化是如此普遍和多样,以至于很难对性能做出精确的说明。此次发布中的变化比以往任何时候都更为广泛,其中包括一个新的垃圾收集器和运行时到 Go 的转换。有些程序可能会运行得更快,有些则更慢。平均而言,Go 1 基准测试套件中的程序在 Go 1.5 中比在 Go 1.4 中运行快几个百分点,而如上所述,垃圾收集器的暂停时间显著缩短,几乎总是低于 10 毫秒。
Go 1.5 中的构建速度将慢大约两倍。编译器和链接器从 C 自动翻译到 Go 导致了非惯用的 Go 代码,与编写良好的 Go 代码相比,其性能较差。分析工具和重构有助于改进代码,但仍有许多工作要做。Go 1.6 及未来版本将继续进行进一步的分析和优化。有关更多详细信息,请参阅这些幻灯片和相关的视频。
标准库
Flag
flag 包的 PrintDefaults
函数和 FlagSet
上的方法已修改,以创建更好的用法消息。格式已更改为更人性化,在用法消息中,用反引号引起来的单词被视为要在用法消息中显示的标志操作数的名称。例如,使用以下调用创建的标志,
cpuFlag = flag.Int("cpu", 1, "run `N` processes in parallel")
将显示帮助消息,
-cpu N
run N processes in parallel (default 1)
此外,现在只有当默认值不是该类型的零值时才列出。
math/big 中的浮点数
math/big
包有一个新的基本数据类型 Float
,它实现了任意精度浮点数。Float
值由布尔符号、可变长度尾数和 32 位固定大小有符号指数表示。Float
的精度(尾数大小,以位为单位)可以显式指定,否则由创建值的第一个操作确定。创建后,Float
的尾数大小可以用 SetPrec
方法修改。Floats
支持无穷大的概念,例如由溢出创建的无穷大,但会导致等效于 IEEE 754 NaN 的值会触发 panic。Float
操作支持所有 IEEE-754 舍入模式。当精度设置为 24 (53) 位时,在归一化 float32
(float64
) 值范围内保持的操作会产生与这些值上相应的 IEEE-754 算术相同的结果。
Go 类型
go/types
包迄今为止一直在 golang.org/x
仓库中维护;从 Go 1.5 开始,它已迁移到主仓库。旧位置的代码现已弃用。该包中还有一个适度的 API 更改,将在下面讨论。
与此迁移相关联,go/constant
包也移到了主仓库;它以前是 golang.org/x/tools/exact
。 go/importer
包也移到了主仓库,以及上面描述的一些工具。
网络
net 包中的 DNS 解析器几乎总是使用 cgo
来访问系统接口。Go 1.5 中的一项更改意味着在大多数 Unix 系统上,DNS 解析将不再需要 cgo
,这简化了在这些平台上的执行。现在,如果系统的网络配置允许,原生 Go 解析器就足够了。此更改的重要影响是每个 DNS 解析都占用一个 goroutine 而不是一个线程,因此具有多个未完成 DNS 请求的程序将消耗更少的操作系统资源。
如何运行解析器的决定在运行时而不是构建时应用。用于强制使用 Go 解析器的 netgo
构建标签不再必要,尽管它仍然有效。新的 netcgo
构建标签在构建时强制使用 cgo
解析器。要在运行时强制 cgo
解析,请在环境中设置 GODEBUG=netdns=cgo
。更多调试选项记录在此处。
此更改仅适用于 Unix 系统。Windows、Mac OS X 和 Plan 9 系统行为与以前相同。
反射
reflect
包有两个新函数:ArrayOf
和 FuncOf
。这些函数类似于现有的 SliceOf
函数,在运行时创建新类型来描述数组和函数。
加固
通过使用 go-fuzz
工具进行随机测试,在标准库中发现了数十个错误。修复了 archive/tar
、archive/zip
、compress/flate
、encoding/gob
、fmt
、html/template
、image/gif
、image/jpeg
、image/png
和 text/template
包中的错误。这些修复增强了实现对不正确和恶意输入的抵御能力。
对库的微小更改
archive/zip
包的Writer
类型现在有一个SetOffset
方法,用于指定在输出流中写入存档的位置。bufio
包中的Reader
现在有一个Discard
方法,用于从输入中丢弃数据。- 在
bytes
包中,Buffer
类型现在有一个Cap
方法,用于报告缓冲区内分配的字节数。同样,在bytes
和strings
包中,Reader
类型现在有一个Size
方法,用于报告底层切片或字符串的原始长度。 bytes
和strings
包现在都有一个LastIndexByte
函数,用于在参数中定位具有该值的最右侧字节。crypto
包有一个新的接口Decrypter
,它抽象了非对称解密中使用的私钥的行为。- 在
crypto/cipher
包中,Stream
接口的文档已针对源和目标长度不同时的行为进行了澄清。如果目标短于源,则该方法将 panic。这并非实现上的更改,仅是文档上的更改。 - 同样在
crypto/cipher
包中,现在支持 AES 的伽罗瓦/计数器模式 (GCM) 中除 96 字节以外的其他随机数长度,某些协议需要这些长度。 - 在
crypto/elliptic
包中,CurveParams
结构体中现在有一个Name
字段,并且包中实现的曲线已命名。对于依赖曲线的密码系统,这些名称提供了一种更安全的方式来选择曲线,而不是通过其位大小进行选择。 - 同样在
crypto/elliptic
包中,Unmarshal
函数现在验证点是否实际在曲线上。(如果不在,函数返回 nil)。此更改可以防御某些攻击。 crypto/sha512
包现在支持 SHA-512 哈希算法的两个截断版本,SHA-512/224 和 SHA-512/256。crypto/tls
包的最低协议版本现在默认为 TLS 1.0。旧的默认值 SSLv3,如果需要,仍然可以通过Config
获得。crypto/tls
包现在支持 RFC 6962 中指定的签名证书时间戳 (SCT)。如果服务器在Certificate
结构中列出它们,则服务器会提供它们;如果客户端请求它们并存在,则在ConnectionState
结构中公开它们。- 之前仅通过
OCSPResponse
方法可用的附带 OCSP 响应到crypto/tls
客户端连接,现在已在ConnectionState
结构中公开。 crypto/tls
服务器实现现在将始终调用Config
结构中的GetCertificate
函数来为连接选择证书(如果没有提供)。- 最后,
crypto/tls
包中的会话票证密钥现在可以在服务器运行时更改。这是通过Config
类型的新SetSessionTicketKeys
方法完成的。 - 在
crypto/x509
包中,通配符现在只在 规范中定义的 leftmost 标签中接受。 - 同样在
crypto/x509
包中,未知关键扩展的处理方式已更改。它们过去会导致解析错误,但现在它们被解析,并且仅在Verify
中导致错误。Certificate
的新字段UnhandledCriticalExtensions
记录了这些扩展。 database/sql
包的DB
类型现在有一个Stats
方法来检索数据库统计信息。debug/dwarf
包有大量补充,以更好地支持 DWARF 版本 4。例如,请参见新类型Class
的定义。debug/dwarf
包现在也支持解码 DWARF 行表。debug/elf
包现在支持 64 位 PowerPC 架构。encoding/base64
包现在通过两个新的编码变量RawStdEncoding
和RawURLEncoding
支持无填充编码。encoding/json
包现在在 JSON 值不适合其要解组的目标变量或组件时返回UnmarshalTypeError
。encoding/json
的Decoder
类型有一个新方法,提供了一个用于解码 JSON 文档的流式接口:Token
。它还与Decode
的现有功能互操作,后者将继续执行已通过Decoder.Token
启动的解码操作。flag
包有一个新函数UnquoteUsage
,用于协助使用上述新约定创建用法消息。- 在
fmt
包中,Value
类型的值现在打印它所持有的内容,而不是使用reflect.Value
的Stringer
方法,后者会生成诸如<int Value>
之类的东西。 go/ast
包中的EmptyStmt
类型现在有一个布尔字段Implicit
,它记录分号是隐式添加的还是存在于源代码中的。- 为了向前兼容,
go/build
包为 Go 有朝一日可能支持的多种架构保留了GOARCH
值。这并非承诺它一定会支持。此外,Package
结构体现在有一个PkgTargetRoot
字段,用于存储(如果已知)安装时与架构相关的根目录。 - (新迁移的)
go/types
包允许通过将新的Qualifier
函数类型作为参数传递给多个函数来控制附加到包级名称的前缀。这是一个包的 API 更改,但由于它对于核心来说是新的,因此它没有破坏 Go 1 兼容性规则,因为使用该包的代码必须在其新位置显式请求它。要更新,请在您的包上运行go fix
。 - 在
image
包中,Rectangle
类型现在实现了Image
接口,因此Rectangle
可以用作绘图时的掩码。 - 同样在
image
包中,为了协助处理某些 JPEG 图像,现在支持 4:1:1 和 4:1:0 YCbCr 子采样以及基本的 CMYK 支持,由新的image.CMYK
结构体表示。 image/color
包添加了基本的 CMYK 支持,通过新的CMYK
结构体、CMYKModel
颜色模型和CMYKToRGB
函数,以满足某些 JPEG 图像的需求。- 同样在
image/color
包中,将YCbCr
值转换为RGBA
变得更加精确。以前,低 8 位只是高 8 位的回声;现在它们包含更准确的信息。由于旧代码的回声特性,uint8(r)
操作以提取 8 位红色值有效,但这是不正确的。在 Go 1.5 中,该操作可能会产生不同的值。正确的代码始终是选择高 8 位:uint8(r>>8)
。顺便说一句,image/draw
包为此类转换提供了更好的支持;有关更多信息,请参阅这篇博客文章。 - 最后,从 Go 1.5 开始,
Index
中的最接近匹配检查现在会考虑 alpha 通道。 image/gif
包包含了一些泛化。多帧 GIF 文件现在可以有一个与所有包含的单帧边界不同的整体边界。此外,GIF
结构体现在有一个Disposal
字段,用于指定每个帧的处理方法。io
包添加了一个CopyBuffer
函数,它类似于Copy
但使用调用者提供的缓冲区,允许控制分配和缓冲区大小。log
包有一个新的LUTC
标志,它会导致时间戳以 UTC 时区打印。它还为用户创建的记录器添加了一个SetOutput
方法。- 在 Go 1.4 中,
Max
未检测到所有可能的 NaN 位模式。这在 Go 1.5 中已修复,因此在包含 NaN 的数据上使用math.Max
的程序可能会表现出不同的行为,但现在根据 IEEE754 对 NaN 的定义是正确的。 math/big
包为整数添加了一个新的Jacobi
函数,并为Int
类型添加了一个新的ModSqrt
方法。- mime 包添加了一个新的
WordDecoder
类型来解码包含 RFC 204 编码单词的 MIME 头。它还提供了BEncoding
和QEncoding
作为 RFC 2045 和 RFC 2047 编码方案的实现。 mime
包还添加了一个ExtensionsByType
函数,该函数返回已知与给定 MIME 类型相关联的 MIME 扩展名。- 有一个新的
mime/quotedprintable
包,它实现了 RFC 2045 定义的 quoted-printable 编码。 net
包现在将通过依次尝试每个 IP 地址直到成功来Dial
主机名。Dialer.DualStack
模式现在通过给第一个地址族 300 毫秒的先行时间来实现 Happy Eyeballs (RFC 6555);此值可以通过新的Dialer.FallbackDelay
覆盖。net
包中错误返回的类型存在的一些不一致之处已得到整理。大多数现在返回一个OpError
值,其中包含比以前更多的信息。此外,OpError
类型现在包含一个Source
字段,用于保存本地网络地址。net/http
包现在支持从服务器Handler
设置尾部。有关详细信息,请参阅ResponseWriter
的文档。- 通过设置新的
Request.Cancel
字段,现在有一种取消net/http
Request
的新方法。它受http.Transport
支持。Cancel
字段的类型与context.Context.Done
返回值兼容。 - 同样在
net/http
包中,有一段代码用于忽略Time
在ServeContent
函数中的零值。从 Go 1.5 开始,它现在也忽略等于 Unix 纪元的时间值。 net/http/fcgi
包导出了两个新错误:ErrConnClosed
和ErrRequestAborted
,用于报告相应的错误情况。net/http/cgi
包有一个错误,它错误处理了环境变量REMOTE_ADDR
和REMOTE_HOST
的值。这已得到修复。此外,从 Go 1.5 开始,该包设置了REMOTE_PORT
变量。net/mail
包添加了一个AddressParser
类型,可以解析邮件地址。net/smtp
包现在有一个TLSConnectionState
访问器,用于Client
类型,它返回客户端的 TLS 状态。os
包有一个新的LookupEnv
函数,它类似于Getenv
,但可以区分空环境变量和缺失环境变量。os/signal
包添加了新的Ignore
和Reset
函数。runtime
、runtime/trace
和net/http/pprof
包各自有新函数来支持上述跟踪设施:ReadTrace
、StartTrace
、StopTrace
、Start
、Stop
和Trace
。请参阅各自的文档了解详细信息。runtime/pprof
包默认现在在所有内存配置文件中包含总体内存统计信息。strings
包有一个新的Compare
函数。此函数的存在是为了与bytes
包保持对称,但由于字符串本身支持比较,因此在其他方面是不必要的。sync
包中的WaitGroup
实现现在诊断代码,该代码在调用Add
和从Wait
返回之间存在竞争。如果检测到此情况,实现会 panic。- 在
syscall
包中,LinuxSysProcAttr
结构体现在有一个GidMappingsEnableSetgroups
字段,这是 Linux 3.19 中安全更改所必需的。在所有 Unix 系统上,该结构体还具有新的Foreground
和Pgid
字段,以便在执行时提供更多控制。在 Darwin 上,现在有一个Syscall9
函数来支持具有过多参数的调用。 testing/quick
现在将为指针类型生成nil
值,从而可以与递归数据结构一起使用。此外,该包现在支持生成数组类型。- 在
text/template
和html/template
包中,过大而无法表示为 Go 整数的整数常量现在会触发解析错误。以前,它们被悄悄地转换为浮点数,从而丢失了精度。 - 同样在
text/template
和html/template
包中,一个新的Option
方法允许自定义模板在执行期间的行为。唯一实现的选项允许控制在索引 map 时如何处理缺失的键。默认值(现在可以覆盖)与以前一样:继续使用无效值。 time
包的Time
类型有一个新方法AppendFormat
,可用于在打印时间值时避免分配。unicode
包和整个系统中的相关支持已从 7.0 版升级到 Unicode 8.0。