- 该文档翻译基于go1.6的Go 1.6 Release Notes
??
所标志的语句表示有疑问http://localhost:6060
是用go1.6中godoc命令搭建的本地文档的访问url.- 欢迎大家指正,原文:https://github.com/meilihao/TranslateProject/blob/master/201602%20Go%201.6%20Release%20Notes.md.
在1.5发布6个月后,Go再次发布了最新的v1.6.其主要变化体现在语言,运行时和库函数的实现上,但在Go语言规范上没有变化.和往常一样,本次发布仍然保持Go 1时的兼容性承诺.我们预计几乎所有的go程序都可以像以前一样编译和运行.
本次发布新增了Linux on 64-bit MIPS和Android on 32-bit x86的移植;制定了在C中共享Go指针的规则;支持透明和自动地使用HTTP/2;新的模板重用机制.
本次发布没有语言变化.
Go1.6在linux on 64-bit MIPS(linux/mips64 and linux/mips64le)上添加了实验性的移植支持.这些移植支持cgo,但仅支持internal连接(ps: C语言连接3属性:external,internal,none).
Go1.6也在Android on 32-bit x86(android/386)上进行了实验性的移植.
在FreeBSD上,Go1.6默认使用clang而不是gcc,做为外部的C编译器.
在linux的小端64-bit PowerPC(linux/ppc64le)上,Go1.6已支持在cgo中使用external连接,且功能也大致完整了.
在NaCI上,Go1.5需要pepper-41版本的SDK,而Go1.6需要更高的版本.
在 32 位 x86 系统中使用 --dynlink 或者 --shared 编译模式,寄存器 CX 被特定内存引用覆盖,可通过编写汇编指令来更改这个行为,详情请看这里.
在cgo中有一个重大改变和一个小改动.
主要的变化是定义了在C中共享Go指针的规则,以确保C语言代码和Go的gc可以共存.简单的说,Go和C可以共享由Go分配的内存,即指向该内存的Go指针可通过作为cgo调用的一部分传递给C,但是,该内存本身不再属于Go分配的内存,同时调用返回后,C不再保留该指针.这些规则在程序执行中由运行时负责检查:如果运行时检测到违规,它会打印诊断信息并使程序崩溃.该检查可通过设置环境变量GODEBUG=cgocheck=0
来禁用,但需要注意绝大多数被检查出来的代码有与gc存在这样或那样的细微的不兼容.禁用检查通常会导致更多的神秘故障.修复有问题的代码应该优于关闭检查,想了解更多信息请查看cgo的文档.
较小的变化是,增加了明确的C.complexfloat和C.complexdouble类型,与Go本身的complex64和complex128区分开来.和其他数值类型一样,C的complex类型和Go的complex类型不再可以互换.
编译工具链几乎不变.在内部,最显著的变化是解析器现在是手写的,而不是由yacc生成.
编译器,连接器和go命令有一个新的标志-msan
,类似于-race
且仅在linux/amd64下可用,其提供了和Clang MemorySanitizer的互操作性.这样的互操作在程序中包含C或者C++代码时非常有用.
连接器有一个新的选项-libgcc
,在连接cgo代码时可用来设置C编译器支持库的预期位置.该选项仅在使用-linkmode=internal
时有效,并且可以设置为none
来禁用支持库.
从Go1.5开始,构建模式的实现已经扩大到了更多的系统.本次发布的版本在android/386, android/amd64, android/arm64, linux/386, and linux/arm64上添加了c-shared模式;在linux/386, linux/arm, linux/amd64, and linux/ppc64le上添加了shared模式;以及在android/386, android/amd64, android/arm, android/arm64, linux/386, linux/amd64, linux/arm, linux/arm64, and linux/ppc64le上添加的新pie模式(生成位置无关的可执行文件).更多信息请查看设计文档.
作为提醒,连接器的-X
标志已经在Go1.5中发生了变化.在Go1.4甚至更早的版本中,它需要两个参数,例如:
-X importpath.name value
在Go1.5中添加了一个使用单个参数的替代语法,通过使用name=value
这样的键值对:
-X importpath.name=value
在Go1.5中旧的语法仍旧有效,但会有提示使用新语法的警告信息.在GO1.6中继续有效并打印警告信息,但在Go1.7中将移除旧语法.
GCC和Go项目的发布时间并不一致.GCC5包含了Go1.4的gccgo,下一版的Go1.6则会包含Go1.5的gccgo.因此,Go1.6可能要到GCC7才能被采纳.
go命令的基本操作不变,但也有些值得一提的变化.
Go1.5时通过将环境变量GO15VENDOREXPERIMENT
设为1来实验性地引入vendoring的支持,在Go1.6中将继续支持该特性,且不再是实验性的,已变为默认设置,但可通过设置GO15VENDOREXPERIMENT为0来禁用.Go1.7移除该环境变量.
默认启用vendoring最可能引发的问题是因为源码中已包含一个叫vendor的文件夹,但其中的内容不希望按照新的vendoring语义来解析.在这种情况下,最简单的解决办法是重命名文件夹(即文件名不再是vendor),并更新相关引用的路径.
更多vendoring的信息,请查看go命令文档和设计文档.
新的构建标志-msan
让go编译器支持LLVM的memory sanitizer.这样做的目的主要是可用memory sanitizer检查连接到的C或者C++代码.
Go1.5引入了go doc
命令,通过包名即可查看其使用方法.比如go doc http
.在模糊情况下,Go1.5根据字典排序选取接近的导入路径??.在Go1.6中采用更短的导入路径来取代字典比较??.这种变化带来的影响是原先的包内容将优先于vendor内容??.成功的搜索往往会让程序跑等更流畅.
go vet
命令现在诊断传递给Printf
函数的作为参数的函数或值,比如用f替代f()时??.
和以前一样,变动是普遍和多样的,以至于很难精准的描述性能变化.某些程序可能运行地更快,有些更慢.Go1.6在Go 1基准测试套件中比Go1.5更快了.GC停顿比Go1.5更短了,在使用大量内存的程序上特别明显.
显著的实现优化给包compress/bzip2, compress/gzip, crypto/aes, crypto/elliptic, crypto/ecdsa,和sort带来了超过10%的性能改进.
Go1.6的net/http包透明地支持全新的HTTP/2协议.Go的客户端和服务器在使用https时将自动使用HTTP/2.Go中并没有特定的可导出的API来处理HTTP/2,就像没有特定的可导出API来处理HTTP/1.1一样.
程序可通过将Transport.TLSNextProto(针对客户端)或Server.TLSNextProto(针对服务端)设置为非nil的空map来禁用HTTP/2.
程序可通过导入golang.org/x/net/http2包来调整HTTP/2的细节,特别是它的ConfigureServer
和ConfigureTransport
函数.
运行时添加了轻量的,更有效的并发误用检查的maps.和以前一样,如果一个goroutine写入map,其他goroutine应不能并发地读写该map.如果运行时监测到这种情况,它将打印诊断信息并crash程序.要了解更多信息应在race detector(可以更加可靠地识别出竞争并给出更多的信息)下运行程序.
程序panic时,运行时现在只打印正在运行的goroutine栈的信息,不再是所有的goroutines.通常只有当前的goroutine是和panic相关的,所以省略其他会显著地减少不相干的crash信息.如果想查看crash中所有的goroutines栈信息,可将环境变量GOTRACEBACK设为all或重新运行程序在crash前调用debug.SetTraceback.了解更多信息可查看运行时的文档.
更新:现在未捕捉到的panic使整个程序dump时,例如,一个超时被检测到或明确地处理一个收到的信号,允许在panic前调用debug.SetTraceback("all").搜索
signal.Notify
的使用可能有利于辨认出这些代码.
在Windows上,Go在1.5及早先的版本中,通过在启动时调用timeBeginPeriod(1)
强制将Windows全局计时器的精度设为1ms.现在Go不再需要这个来优化调度器的性能,同时不再允许在其他系统上修改全局精度(其会导致其他问题),所以已经移除该调用.
当使用-buildmode=c-archive
或-buildmode=c-shared
来创建一个静态或动态库时,信号的处理方式已经发生改变.在Go1.5中,静态或动态库内置一个信号处理器来处理大多数信号.在Go1.6中内置的信号处理器仅在runtime panic时处理代码中的同步信号:SIGBUS, SIGFPE, SIGSEGV
.查看os/signal
可获得更多细节.
reflect
包已经解决了一个长期存在于gc和gccgo工具链中关于内嵌的不可导出的struct类型包含可导出字段时的不兼容问题.使用反射来获取数据结构的代码,特别是使用encoding/json
和encoding/xml
包实现序列化的代码,可能需要更新.
问题出现在使用反射一个内嵌不可导出的struct类型字段时变成可导出的该struct类型.在这种情况下,reflect会错误地认为内嵌字段是可导出的(通过返回一个空的Field.PkgPath).现在,它会正确地认为该字段是不可导出的,但是会忽略这一事实当可导出字段包含该struct时.
更新: 通常情况下,早先代码通过使用
f.PkgPath != ""
来排除不可用的字段,现在需要使用
f.PkgPath != "" && !f.Anonymous
例如,查看encoding/json
和encoding/xml
的实现.
在sort
包,Sort
函数的实现已经被重写,通过在调用Interface
接口的Less
和Swap
方法时节省相应的总时间以带来10%性能的提升.新算法会选择不同的排序方式,以前是通过比较值是否相等,即成对调用Less(i, j)和Less(j, i)是否为false来实现.
更新: Sort
的实现不再保证相同值的最终顺序,但新的行为仍可能打破这种期望以实现特定的排序.这样的程序会完善它们的Less实现或使用Stable
以获得期望的顺序或者,这等于保留了原始相同值的输入顺序.
text/template
包有两个显著的新功能,使得编写模板更加容易.
首先,它可以去除环绕在模板action({{}}
)周围的空格,使模板定义更有可读性.一个减号出现在action的开头说明去除该action前的空格,一个减号出现在action的结尾说明去除该action后的空格.例如,模板
{{23 -}}
<
{{- 45}}
会格式化为23<45
.
其次,新的action{{block}}
,和允许重新定义一个已有模板相结合,提供了一种简单的方式来定义模板的片段,其可以在不同的实例中被替换.在text/template中有一个案例演示了这一新功能.
请查看原文,这里略.