Go 1.5 Release Notes

Introduction to Go 1.5

最新的Go版本1.5版是一个重要版本,其中包括对实现的重大体系结构更改. 尽管如此,我们预计几乎所有Go程序都将像以前一样继续编译和运行,因为该版本仍保持了Go 1 的兼容性承诺 .

该实施的最大发展是:

下面讨论了对实现和工具的这些以及许多其他更改.

该版本还包含一项涉及地图文字的小语言更改.

最后, 发布的时间偏离了通常的六个月间隔,既提供了更多的时间来准备该主要发布,又为之后的时间表调整了发布日期,以便更方便地进行计时.

Changes to the language

Map literals

由于疏忽,允许从切片文字中省略元素类型的规则未应用于映射键. Go 1.5中已对此进行了纠正 . 一个例子将使这一点变得清楚. 从Go 1.5开始,此地图文字

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",
}

The Implementation

No more C

现在,可以在Go和汇编器中实现编译器和运行时,而无需C.树中剩下的唯一C源代码与cgocgo . 在1.4及更早版本的树中有一个C编译器. 它用于构建运行时. 必须使用定制的编译器,以部分确保C代码将与goroutine的堆栈管理一起使用. 由于运行时现在位于Go中,因此不需要此C编译器并且它已经消失了. 消除C的详细过程在其他地方讨论.

从C的转换是在为该作业创建的自定义工具的帮助下完成的. 最重要的是,实际上是通过将C代码自动转换为Go来移动编译器的. 实际上,它是同一程序的另一种语言. 这不是编译器的新实现,因此我们希望该过程不会引入新的编译器错误. 此演示文稿的幻灯片中提供了此过程的概述.

Compiler and tools

独立于但受Go的鼓舞,这些工具的名称已更改. 6g8g等旧名称消失了; 相反,只有一个二进制文件(可通过go tool compile访问),将Go源代码编译为适合$GOARCH$GOOS指定的体系结构和操作系统的二进制文件. 同样,现在有一个链接器( go tool link )和一个汇编器( go tool asm ). 链接器是从旧的C实现自动翻译过来的,但是汇编器是新的本机Go实现,下面将详细讨论.

类似于删除名称6g8g等,现在为编译器和汇编器的输出赋予纯后缀.o后缀,而不是.8.6等.

Garbage collector

作为设计文档中概述的开发的一部分,垃圾收集器已重新设计为1.5. 通过结合高级算法,更好地调度收集器以及与用户程序并行运行更多收集,预期延迟要比以前版本中的收集器低得多. 收集器的"停止世界"阶段几乎总是在10毫秒以下,并且通常更少.

对于受益于低延迟的系统(例如用户响应网站),新收集器的预期延迟下降可能很重要.

在GopherCon 2015的一次演讲中介绍了新收藏家的细节.

Runtime

在Go 1.5中,更改了goroutine的安排顺序. 语言从未定义过调度程序的属性,但是此更改可能会破坏依赖于调度顺序的程序. 我们已经看到一些(错误的)程序受到此更改的影响. 如果您的程序隐式依赖于调度顺序,则需要对其进行更新.

另一个潜在的突破性变化是,运行时现在将由GOMAXPROCS定义的同时运行的默认线程数设置为CPU上可用的内核数. 在以前的版本中,默认值为1.不希望与多个内核一起运行的程序可能会无意间中断. 可以通过消除限制或通过显式设置GOMAXPROCS来更新它们. 有关此更改的详细讨论,请参见设计文档 .

Build

现在已经在Go中实现了Go编译器和运行时,现在必须有Go编译器才能从源代码编译发行版. 因此,要构建Go核心,必须已经有一个可用的Go发行版. (不使用内核的Go程序员不受此更改的影响.)任何Go 1.4或更高版本(包括gccgo )都可以使用. 有关详细信息,请参见设计文档 .

Ports

很大程度上是由于该行业不再使用32位x86架构,因此提供的二进制下载数量减少了1.5. 仅针对amd64体系结构而不是386提供OS X操作系统的发行版. 同样,Snow Leopard(Apple OS X 10.6)的端口仍可使用,但不再作为下载版本发布或维护,因为Apple不再维护该版本的操作系统. 另外,不再支持Dragonfly dragonfly/386端口,因为DragonflyBSD本身不再支持32位386体系结构.

但是,可以从源代码构建几个新的端口. 这些包括darwin/armdarwin/arm64 . 新的端口linux/arm64大部分就位,但是仅使用外部链接才支持cgo .

ppc64ppc64le (64位PowerPC,大端和小端)也可以作为实验使用. 这两个端口都支持cgo但仅支持内部链接.

On FreeBSD, Go 1.5 requires FreeBSD 8-STABLE+ because of its new use of the SYSCALL instruction.

在NaCl上,Go 1.5需要SDK版本Pepper-41. 由于从NaCl运行时中删除了sRPC子系统,因此以后的Pepper版本不兼容.

在Darwin上,可以通过ios build标签禁用系统X.509证书接口的使用.

Solaris端口现在完全支持cgo以及netcrypto/x509软件包以及许多其他修复和改进.

Tools

Translating

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

但是,汇编器是一个新程序. 如下所述.

Renaming

分别是编译器( 6g8g等),汇编器( 6a8a等)和链接器( 6l8l等)的程序套件均已合并为一个已配置的工具由环境变量GOOSGOARCH . 旧名字不见了; 通过go tool机制可以通过go tool compilego tool asm and go tool link . 同样,中间目标文件的文件后缀.6.8等也消失了; 现在它们只是普通的.o文件.

例如,要使用这些工具直接在amd64上为达尔文构建并链接程序,而不是通过go build ,可以运行以下程序:

$ export GOOS=darwin GOARCH=amd64
$ go tool compile program.go
$ go tool link program.o

Moving

由于go/types包现在已移至主存储库(请参见下文),因此vetcover工具也已移至. 它们不再保存在外部golang.org/x/tools存储库中,尽管(不建议使用)源仍驻留在该golang.org/x/tools与旧版本兼容.

Compiler

如上所述,Go 1.5中的编译器是一个从旧C源代码转换而来的Go程序,它替换了6g8g等. 其目标由环境变量GOOSGOARCH .

1.5编译器几乎等效于旧的编译器,但一些内部细节已更改. 一个重要的变化是,常量的评估现在使用了math/big包,而不是高精度算术的定制(且测试程度较低)实现. 我们认为这不会影响结果.

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

Assembler

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

The new assembler is very nearly compatible with the previous ones, but there are a few changes that may affect some assembler source files. See the updated assembler guide for more specific information about these changes. In summary:

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

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

一个小的变化是某些旧的汇编程序允许使用该符号

constant=value

定义一个命名常量. 由于这始终可以通过仍受支持的传统的类似C的#define标记来完成(汇编器包括简化C预处理器的实现),因此删除了该功能.

The linker in Go 1.5 is now one Go program, that replaces 6l, 8l, etc. Its operating system and instruction set are specified by the environment variables GOOS and GOARCH.

还有其他一些更改. 最重要的是添加了-buildmode选项,该选项扩展了链接的样式; 它现在支持诸如建立共享库和允许其他语言调用Go库之类的情况. 其中一些在设计文档中概述. 有关可用构建模式及其使用的列表,请运行

$ go help buildmode

另一个小的变化是,链接器不再在Windows可执行文件的标头中记录构建时间戳. 另外,尽管可能已解决,但Windows cgo可执行文件缺少某些DWARF信息.

最后, -X标志,它带有两个参数,如

-X importpath.name value

now also accepts a more common Go flag style with a single argument that is itself a name=value pair:

-X importpath.name=value

尽管旧语法仍然有效,但建议将脚本等中的此标志使用更新为新格式.

Go command

go命令的基本操作未更改,但是有许多更改值得注意.

先前的版本引入了软件包内部目录的想法,该目录无法通过go命令导入. 在1.4中,通过在核心存储库中引入一些内部元素对它进行了测试. 如设计文档中所建议,该更改现在可用于所有存储库. 这些规则在设计文档中进行了说明,但总而言之,目录internal或目录internal任何程序包都可以由植于同一子树中的程序包导入. 此更改可能会无意间破坏了具有名为internal目录元素的现有软件包,这就是在上一发行版中进行广告宣传的原因.

软件包处理方式的另一个变化是实验性地增加了对"供应商"的支持. 有关详细信息,请参见go命令文档设计文档 .

也有一些小的变化. 阅读文档以获取全部详细信息.

Go vet command

现在, go tool vet命令可以更彻底地验证struct标记.

Trace command

新工具可用于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 command

发行了一些版本,删除了go doc命令,因为它是不必要的. 人们总是可以运行" godoc . ". 1.5版本引入了一个新的go doc命令,该命令具有比godoc更加方便的命令行界面. 它是专门为命令行使用而设计的,根据调用,它为包或其元素提供了更紧凑,更集中的文档介绍. 它还提供了不区分大小写的匹配,并支持显示未导出符号的文档. 有关详细信息,请运行" go help doc ".

Cgo

现在,在解析#cgo ,调用${SRCDIR}会扩展到源目录的路径中. 这允许将涉及相对于源代码目录的文件路径的选项传递给编译器和链接器. 没有扩展,当当前工作目录更改时,路径将无效.

Solaris now has full cgo support.

在Windows上,默认情况下,cgo现在使用外部链接.

当C结构以零大小的字段结尾但结构本身不是零大小时,Go代码不再可以引用零大小的字段. 任何此类引用都必须重写.

Performance

与往常一样,这些更改是如此笼统和多变,以至于很难对性能进行精确的表述. 此次更改的范围甚至比此版本中的常规范围更广,该版本包括一个新的垃圾回收器以及将运行时转换为Go的功能. 有些程序可能运行得更快,有些则运行得更慢. 平均而言,Go 1基准套件中的程序在Go 1.5中的运行速度比在Go 1.4中的运行速度快百分之几,而如上所述,垃圾收集器的暂停时间明显缩短,并且几乎总是少于10毫秒.

Go 1.5中的构建速度将降低大约两倍. 编译器和链接器从C到Go的自动翻译导致单语言的Go代码与编写良好的Go相比性能较差. 分析工具和重构有助于改进代码,但仍有许多工作要做. Go 1.6和更高版本将继续进行进一步的分析和优化. 有关更多详细信息,请参见这些幻灯片和相关视频 .

Core library

Flag

标志包的PrintDefaults函数以及FlagSet方法已被修改以创建更好的用法消息. 格式已更改为更人性化,并且在使用情况消息中,带有" backquotes"的单词被视为标志的操作数的名称,以显示在使用情况消息中. 例如,通过调用创建的标志,

cpuFlag = flag.Int("cpu", 1, "run `N` processes in parallel")

将显示帮助消息,

-cpu N
    	run N processes in parallel (default 1)

此外,现在仅在默认值不是该类型的零值时列出该默认值.

Floats in math/big

math/big程序包具有一个新的基本数据类型Float ,该数据类型实现了任意精度的浮点数. Float值由布尔符号,可变长度的尾数和32位固定大小的带符号表示. Float的精度(尾数以位为单位)可以显式指定,或者由创建该值的第一个操作确定. 创建后,可以使用SetPrec方法修改Float尾数的大小. Floats支持无穷大的概念,如由溢出产生,但是这将导致IEEE 754的NaN等效值触发恐慌. Float运算支持所有IEEE-754舍入模式. 当精度设置为24(53)位时,停留在规范化float32float64 )值范围内的操作将产生与这些值上相应的IEEE-754算术相同的结果.

Go types

到目前为止, 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 build标记,但不再需要. 一个新的netcgo构建标签会在构建时强制使用cgo解析器. 要在运行时强制执行cgo解析,请在环境中设置GODEBUG=netdns=cgo . 此处记录更多调试选项.

此更改仅适用于Unix系统. Windows,Mac OS X和Plan 9系统的行为与以前相同.

Reflect

reflect包具有两个新功能: ArrayOfFuncOf . 这些函数类似于现存的SliceOf函数,它们在运行时创建新类型来描述数组和函数.

Hardening

通过使用go-fuzz工具进行随机测试,在标准库中发现了数十个错误. 错误已修复在archive/tararchive/zipcompress/flateencoding/gobfmthtml/templateimage/gifimage/jpegimage/pngtext/template包中. 该修补程序可针对错误和恶意输入加强实施.

Minor changes to the library

by  ICOPY.SITE