Go 1.2 Release Notes

Introduction to Go 1.2

自2013年4月发布Go 1.1版以来,缩短了发布时间表,以使发布过程更加高效. 此版本(简称Go版本1.2或Go 1.2)在1.1之后大约六个月到达,而1.1在1.0之后出现了一年. 由于时间尺度较短,因此1.2的增量要小于从1.0到1.1的增量,但它仍具有一些重要的发展,包括更好的调度程序和一种新的语言功能. 当然,Go 1.2保留了兼容性承诺 . 使用Go 1.1(或1.0)构建的绝大多数程序在移至1.2时都不会进行任何更改,尽管对语言的一角引入了一种限制可能会暴露已经不正确的代码(请参阅参考资料的讨论). 使用nil ).

Changes to the language

为了确定规范,澄清了一个极端的情况,对程序有影响. 还有一项新的语言功能.

Use of nil

该语言现在指定,出于安全原因,保证使用nil指针可以触发运行时恐慌. 例如,在Go 1.0中,给定的代码如下

type T struct {
    X [1<<24]byte
    Field int32
}

func main() {
    var x *T
    ...
}

nil指针x可能用于错误地访问内存:表达式x.Field可以访问地址1<<24内存. 为了防止这种不安全的行为,在Go 1.2中,编译器现在保证通过nil指针进行的任何间接操作(例如此处所示,但在指向数组的nil指针,nil接口值,nil slice等)中的任何操作都将导致恐慌或返回正确,安全的非零值. 简而言之,任何显式或隐式需要评估nil地址的表达式都是错误. 该实现可能会向编译的程序中注入额外的测试以强制执行此行为.

更多细节在设计文档中 .

更新 :大多数依赖于旧行为的代码是错误的,并且在运行时将失败. 此类程序将需要手动更新.

Three-index slices

当在现有阵列或切片上使用切片操作时,Go 1.2增加了指定容量和长度的功能. 切片操作通过描述已创建的数组或切片的连续部分来创建新切片:

var array [10]int
slice := array[2:4]

切片的容量是即使切片后切片也可以容纳的最大元素数; 它反映了基础数组的大小. 在此示例中, slice变量的容量为8.

Go 1.2添加了新的语法,以允许切片操作指定容量以及长度. 第二个冒号引入了容量值,该值必须小于或等于源切片或阵列的容量,并针对原点进行了调整. 例如,

slice = array[2:4:7]

将切片设置为与前面的示例相同的长度,但是现在其容量仅为5个元素(7-2). 无法使用这个新的slice值来访问原始数组的最后三个元素.

在这种三索引表示法中,缺少的第一索引( [:i:j] )默认为零,但必须始终明确指定其他两个索引. Go的未来版本可能会引入这些索引的默认值.

更多细节在设计文档中 .

更新 :这是向后兼容的更改,不影响任何现有程序.

Changes to the implementations and tools

Pre-emption in the scheduler

在以前的版本中,永远循环的goroutine可能会使同一线程上的其他goroutine饿死,当GOMAXPROCS仅提供一个用户线程时,这是一个严重的问题. 在Go 1.2中,部分解决了此问题:调度程序在输入函数时偶尔被调用. 这意味着任何包含(非内联的)函数调用的循环都可以被抢占,从而允许其他goroutine在同一线程上运行.

Limit on the number of threads

Go 1.2对单个程序在其地址空间中可能具有的线程总数引入了可配置的限制(默认为10,000),以避免在某些环境中出现资源匮乏的问题. 请注意,goroutines被多路复用到线程上,因此此限制并不直接限制goroutines的数量,仅限制可以在系统调用中同时阻止的数量. 实际上,这个极限很难达到.

runtime/debug包中的新SetMaxThreads函数控制线程数限制.

更新 :很少有函数会受到限制的影响,但是如果程序由于达到限制而死了,则可以对其进行修改以调用SetMaxThreads来设置更高的计数. 更好的方法是将程序重构为需要更少的线程,从而减少内核资源的消耗.

Stack size

在Go 1.2中,创建goroutine时堆栈的最小大小已从4KB提高到8KB. 许多程序在使用旧大小时都遇到了性能问题,这倾向于在性能关键的部分中引入昂贵的堆栈段切换. 新数字是通过经验测试确定的.

另一方面, runtime/debug包中的新函数SetMaxStack控制单个goroutine堆栈的最大大小. 在64位系统上,默认值为1GB;在32位系统上,默认值为250MB. 在Go 1.2之前,失控的递归很容易消耗掉计算机上的所有内存.

更新 :增加的最小堆栈大小可能会导致具有许多goroutine的程序使用更多的内存. 没有解决方法,但是未来版本的计划包括新的堆栈管理技术,可以更好地解决该问题.

Cgo and C++

现在, cgo命令将调用C ++编译器来构建用C ++编写的链接库的任何部分. 该文档有更多详细信息.

Godoc and vet moved to the go.tools subrepository

这两个二进制文件仍包含在发行版中,但godoc和vet命令的源代码已移至go.tools子存储库.

另外,godoc程序的核心已拆分为一个 ,而命令本身位于单独的目录中 . 此举使代码易于更新,并且将库和命令分离为本地站点和不同部署方法的自定义二进制文件更加容易.

Updating: Since godoc and vet are not part of the library, no client Go code depends on the their source and no updating is required.

可从golang.org获得的二进制发行版包括这些二进制文件,因此这些发行版的用户不受影响.

从源代码构建时,用户必须使用" go get"来安装godoc和vet. (这些二进制文件将继续安装在其通常的位置,而不是$GOPATH/bin .)

$ go get code.google.com/p/go.tools/cmd/godoc
$ go get code.google.com/p/go.tools/cmd/vet

Status of gccgo

我们预计将来的GCC 4.9版本将包含对Go 1.2完全支持的gccgo. 在当前(4.8.2)版本的GCC中,gccgo实现了Go 1.1.2.

Changes to the gc compiler and linker

Go 1.2对gc编译器套件的工作方式进行了一些语义上的更改. 大多数用户将不受他们的影响.

现在,当要链接的库中包含C ++时, cgo命令就可以使用. 有关详细信息,请参见cgo文档.

当程序没有package子句时,gc编译器显示其起源的残留细节:它假定文件位于package main . 过去已被删除,缺少的package句现在是错误.

在ARM上,工具链支持"外部链接",这是朝着能够与gc工具链建立共享库并为必要的环境提供动态链接支持的一步.

在具有5a的ARM运行时中,曾经有可能直接使用R9R10来引用运行时内部的m (机器)和g (goroutine)变量. 现在必须用它们的专有名称来引用它们.

还对臂,所述5l接头(原文如此)现在定义了MOVBSMOVHS作为同义词指令MOVBMOVH ,以更清楚符号和无符号的子字移动之间的间隔; 未签名的版本已经存在,带有U后缀.

Test coverage

go test一项主要新功能是,它现在可以计算并在新安装的单独的" go tool cover"程序的帮助下显示测试覆盖率结果.

The cover tool is part of the go.tools subrepository. It can be installed by running

$ go get code.google.com/p/go.tools/cmd/cover

封面工具有两件事. 首先,为" go test"提供-cover标志时,它将自动运行以重写包的源并插入检测语句. 然后将测试编译并照常运行,并报告基本覆盖率统计信息:

$ go test -cover fmt
ok  	fmt	0.060s	coverage: 91.4% of statements
$

其次,对于更详细的报告,"执行测试"的不同标志可以创建一个覆盖配置文件,然后可以使用" go工具覆盖"调用的覆盖程序进行分析.

运行命令可以找到有关如何生成和分析覆盖率统计信息的详细信息

$ go help testflag
$ go tool cover -help

The go doc command is deleted

" go doc"命令被删除. 请注意,不会删除godoc工具本身,而只是通过go命令对其进行包装. 它所做的只是按包路径显示了包的文档,godoc本身已经具有更大的灵活性. 因此,已删除该文档以减少文档工具的数量,并作为godoc重组的一部分,鼓励将来使用更好的选择.

Updating: For those who still need the precise functionality of running

$ go doc

在目录中,行为与运行相同

$ godoc .

Changes to the go command

现在, go get命令具有-t标志,该标志使它下载软件包运行的测试的依赖关系,而不仅仅是软件包本身的依赖关系. 默认情况下,像以前一样,不下载测试的依赖项.

Performance

标准库中有许多显着的性能改进. 这里有几个.

Changes to the standard library

The archive/tar and archive/zip packages

archive/tararchive/zip软件包的语义已更改,可能会破坏现有程序. 问题在于它们都提供了os.FileInfo接口的实现,该实现不符合该接口的规范. 特别是,它们的Name方法返回条目的完整路径名,但是接口规范要求该方法仅返回基本名称(最终路径元素).

更新 :由于此行为是新实现的,并且有点模糊,因此可能没有代码依赖于损坏的行为. 如果确实有依赖于此的程序,则需要手动识别并修复它们.

The new encoding package

有一个新的包encoding ,它定义了一组标准编码接口,可用于为诸如encoding/xmlencoding/jsonencoding/binary包构建自定义封送程序和解组程序. 这些新接口已用于整理标准库中的某些实现.

新接口称为BinaryMarshalerBinaryUnmarshalerTextMarshalerTextUnmarshaler . 完整的详细信息在包装的文档和单独的设计文档中 .

The fmt package

fmt软件包的格式化打印例程(如Printf现在允许通过使用格式化规范中的索引操作以任意顺序访问要打印的数据项. 无论是要从参数列表中获取参数进行格式化的地方,无论是作为要格式化的值还是作为宽度或指定整数,都会使用新的可选索引符号[ n ]获取参数n . n的值是1索引的. 在进行这样的索引操作之后,要通过常规处理获取的下一个参数将为n +1.

例如,正常的Printf调用

fmt.Sprintf("%c %c %c\n", 'a', 'b', 'c')

会创建字符串"abc" ,但是使用这样的索引操作,

fmt.Sprintf("%[3]c %[1]c %c\n", 'a', 'b', 'c')

结果为" "cab" . [3]索引访问第三个格式参数,即'c'[1]访问第一个格式参数, 'a' ,然后下一个访存访问紧随其后的参数, 'b' .

此功能的动机是可编程格式的语句,以不同的顺序访问参数以进行本地化,但是它还有其他用途:

log.Printf("trace: value %v of type %[1]T\n", expensiveFunction(a.b[c]))

更新 :格式规范语法的更改严格向下兼容,因此不影响任何工作程序.

The text/template and html/template packages

text/template包在Go 1.2中有几个更改,这两个更改也都反映在html/template包中.

首先,有一些用于比较基本类型的新默认功能. 下表中列出了这些函数,其中显示了它们的名称和相关的熟悉的比较运算符.

Name Operator
eq ==
ne !=
lt <
le <=
gt >
ge >=

这些函数的行为与相应的Go运算符略有不同. 首先,它们仅对基本类型( boolintfloat64string等)进行操作. (Go在某些情况下也允许比较数组和结构.)其次,可以比较值,只要它们是同一类型的值即可:例如,可以将任何有符号整数值与任何其他有符号整数值进行比较. (Go不允许比较int8int16 ). 最后, eq函数(仅)允许将第一个参数与一个或多个后续参数进行比较. 在此示例中的模板

{{if eq .A 1 2 3 }} equal {{else}} not equal {{end}}

如果.A等于1、2或3中的任何 .A则报告"等于".

第二个变化是对语法的少量添加使" if if if"链更易于编写. 不用写

{{if eq .A 1}} X {{else}} {{if eq .A 2}} Y {{end}} {{end}} 

一个可以将第二个" if"折叠为" else",并且只有一个" end",如下所示:

{{if eq .A 1}} X {{else if eq .A 2}} Y {{end}}

这两种形式在效果上是相同的. 区别仅在于语法.

更新 :" else if"更改和比较功能都不会影响现有程序. 通过函数映射已经定义了eq等函数的函数不会受到影响,因为关联的函数映射将覆盖新的默认函数定义.

New packages

有两个新软件包.

Minor changes to the library

下表总结了对该库的一些较小更改,主要是新增内容. 有关每个更改的更多信息,请参见相关的软件包文档.

by  ICOPY.SITE