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 语言的迁移,但受其鼓励,工具的名称已更改。旧名称 6g8g 等已移除;现在只有一个二进制文件,可作为 go tool compile 访问,它将 Go 源代码编译成适合由 $GOARCH$GOOS 指定的架构和操作系统的二进制文件。类似地,现在有一个链接器(go tool link)和一个汇编器(go tool asm)。链接器是从旧的 C 实现自动翻译的,但汇编器是下面将更详细讨论的新原生 Go 实现。

类似于放弃了 6g8g 等名称,编译器和汇编器的输出现在给定一个普通的 .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/armdarwin/arm64。新的 linux/arm64 端口大部分已到位,但 cgo 仅支持使用外部链接。

ppc64ppc64le(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 和软件包netcrypto/x509,以及许多其他修复和改进。

工具

翻译

作为从树中消除 C 的过程的一部分,编译器和链接器从 C 翻译为 Go。这是一个真正的(机器辅助的)翻译,因此新程序本质上是旧程序的翻译版本,而不是带有新错误的新程序。我们相信翻译过程几乎没有引入任何新错误,事实上还发现了许多以前未知的错误,现已修复。

但是,汇编器是一个新程序;它将在下面描述。

重命名

编译器(6g8g 等)、汇编器(6a8a 等)和链接器(6l8l 等)的程序套件已分别整合为一个工具,该工具由环境变量 GOOSGOARCH 配置。旧名称已消失;新工具通过 go tool 机制作为 go tool compilego tool asmgo 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 包现在已移入主仓库(见下文),vetcover 工具也已移动。它们不再在外部 golang.org/x/tools 仓库中维护,尽管(已弃用的)源代码仍保留在那里以与旧版本兼容。

编译器

如上所述,Go 1.5 中的编译器是一个从旧 C 源代码翻译而来的单个 Go 程序,它取代了 6g8g 等。其目标由环境变量 GOOSGOARCH 配置。

1.5 编译器与旧编译器基本等效,但一些内部细节已更改。一个重要的变化是常量评估现在使用 math/big 包,而不是自定义(且测试较少)的高精度算术实现。我们预计这不会影响结果。

仅对于 amd64 架构,编译器有一个新选项 -dynlink,它通过支持引用外部共享库中定义的 Go 符号来协助动态链接。

汇编器

与编译器和链接器一样,Go 1.5 中的汇编器是一个替换汇编器套件(6a8a 等)的单一程序,环境变量 GOARCHGOOS 配置架构和操作系统。与其他程序不同,汇编器是一个完全用 Go 编写的新程序。

新汇编器与以前的汇编器几乎兼容,但有一些更改可能会影响某些汇编源代码文件。有关这些更改的更具体信息,请参阅更新的汇编器指南。总而言之

首先,用于常量的表达式评估略有不同。它现在使用无符号 64 位算术,运算符(+-<< 等)的优先级来自 Go,而不是 C。我们预计这些更改会影响极少数程序,但可能需要手动验证。

也许更重要的是,在 SPPC 只是编号寄存器的别名(例如 ARM 上堆栈指针的 R13 和硬件程序计数器的 R15)的机器上,引用不包含符号的此类寄存器现在是非法的。例如,SP4(SP) 是非法的,但 sym+4(SP) 是可以的。在此类机器上,要引用硬件寄存器,请使用其真实的 R 名称。

一个小的变化是,一些旧汇编器允许使用以下表示法

constant=value

定义一个命名常量。由于使用传统的类似 C 的 #define 表示法(仍然受支持,汇编器包含一个简化的 C 预处理器实现)总是可以做到这一点,因此该功能已删除。

Go 1.5 中的链接器现在是一个 Go 程序,它取代了 6l8l 等。其操作系统和指令集由环境变量 GOOSGOARCH 指定。

还有其他一些变化。最重要的是增加了 -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/exactgo/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 包有两个新函数:ArrayOfFuncOf。这些函数类似于现有的 SliceOf 函数,在运行时创建新类型来描述数组和函数。

加固

通过使用 go-fuzz 工具进行随机测试,在标准库中发现了数十个错误。修复了 archive/tararchive/zipcompress/flateencoding/gobfmthtml/templateimage/gifimage/jpegimage/pngtext/template 包中的错误。这些修复增强了实现对不正确和恶意输入的抵御能力。

对库的微小更改

  • archive/zip 包的 Writer 类型现在有一个 SetOffset 方法,用于指定在输出流中写入存档的位置。
  • bufio 包中的 Reader 现在有一个 Discard 方法,用于从输入中丢弃数据。
  • bytes 包中,Buffer 类型现在有一个 Cap 方法,用于报告缓冲区内分配的字节数。同样,在 bytesstrings 包中,Reader 类型现在有一个 Size 方法,用于报告底层切片或字符串的原始长度。
  • bytesstrings 包现在都有一个 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 包现在通过两个新的编码变量 RawStdEncodingRawURLEncoding 支持无填充编码。
  • encoding/json 包现在在 JSON 值不适合其要解组的目标变量或组件时返回 UnmarshalTypeError
  • encoding/jsonDecoder 类型有一个新方法,提供了一个用于解码 JSON 文档的流式接口:Token。它还与 Decode 的现有功能互操作,后者将继续执行已通过 Decoder.Token 启动的解码操作。
  • flag 包有一个新函数 UnquoteUsage,用于协助使用上述新约定创建用法消息。
  • fmt 包中,Value 类型的值现在打印它所持有的内容,而不是使用 reflect.ValueStringer 方法,后者会生成诸如 <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 头。它还提供了 BEncodingQEncoding 作为 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 包中,有一段代码用于忽略 TimeServeContent 函数中的零值。从 Go 1.5 开始,它现在也忽略等于 Unix 纪元的时间值。
  • net/http/fcgi 包导出了两个新错误:ErrConnClosedErrRequestAborted,用于报告相应的错误情况。
  • net/http/cgi 包有一个错误,它错误处理了环境变量 REMOTE_ADDRREMOTE_HOST 的值。这已得到修复。此外,从 Go 1.5 开始,该包设置了 REMOTE_PORT 变量。
  • net/mail 包添加了一个 AddressParser 类型,可以解析邮件地址。
  • net/smtp 包现在有一个 TLSConnectionState 访问器,用于 Client 类型,它返回客户端的 TLS 状态。
  • os 包有一个新的 LookupEnv 函数,它类似于 Getenv,但可以区分空环境变量和缺失环境变量。
  • os/signal 包添加了新的 IgnoreReset 函数。
  • runtimeruntime/tracenet/http/pprof 包各自有新函数来支持上述跟踪设施:ReadTraceStartTraceStopTraceStartStopTrace。请参阅各自的文档了解详细信息。
  • runtime/pprof 包默认现在在所有内存配置文件中包含总体内存统计信息。
  • strings 包有一个新的 Compare 函数。此函数的存在是为了与 bytes 包保持对称,但由于字符串本身支持比较,因此在其他方面是不必要的。
  • sync 包中的 WaitGroup 实现现在诊断代码,该代码在调用 Add 和从 Wait 返回之间存在竞争。如果检测到此情况,实现会 panic。
  • syscall 包中,Linux SysProcAttr 结构体现在有一个 GidMappingsEnableSetgroups 字段,这是 Linux 3.19 中安全更改所必需的。在所有 Unix 系统上,该结构体还具有新的 ForegroundPgid 字段,以便在执行时提供更多控制。在 Darwin 上,现在有一个 Syscall9 函数来支持具有过多参数的调用。
  • testing/quick 现在将为指针类型生成 nil 值,从而可以与递归数据结构一起使用。此外,该包现在支持生成数组类型。
  • text/templatehtml/template 包中,过大而无法表示为 Go 整数的整数常量现在会触发解析错误。以前,它们被悄悄地转换为浮点数,从而丢失了精度。
  • 同样在 text/templatehtml/template 包中,一个新的 Option 方法允许自定义模板在执行期间的行为。唯一实现的选项允许控制在索引 map 时如何处理缺失的键。默认值(现在可以覆盖)与以前一样:继续使用无效值。
  • time 包的 Time 类型有一个新方法 AppendFormat,可用于在打印时间值时避免分配。
  • unicode 包和整个系统中的相关支持已从 7.0 版升级到 Unicode 8.0