Go 1.14 已发布,附带详细的更新日志
Go 1.14 简介
最新的 Go 版本1.14,在 Go 1.13 之后六个月发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了 Go 1 的 兼容性承诺。我们预计几乎所有的 Go 程序都会像以前一样正常编译和运行,而不会出错。
Go Module 现已具备生产环境中使用的条件,我们鼓励所有用户 迁移到 Go 模块进行依赖关系管理。如果由于 Go 工具链中的问题而无法迁移,请确保该问题具有 Open Issue 文件。(如果问题不在Go1.15
里程碑上,请告诉我们它阻止您迁移的原因,以便我们可以适当地排定优先级。)
语言变更
根据 重叠接口建议,,GO 1.14 现在允许嵌入具有重叠方法集的接口:来自嵌入式接口的方法允许与(嵌入)接口中已存在的方法拥有相同的名称和签名。这解决了通常(但不是唯一的)菱形嵌入图出现的问题。与以前一样,接口中显式声明的方法必须保持 唯一性。
平台支持
Darwin(苹果)
Go 1.14 is the last release that will run on macOS 10.11 El Capitan. Go 1.15 will require macOS 10.12 Sierra or later.
Go 1.14 要求 macOS 10.11 El Capitan 以上。1.15 以后将需要 macOS 10.12 Sierra 或更高版本。
Go 1.14 是最后一个在 32 位的 macOS (darwin/386
) 上运行的版本,因为 macOS 从 10.15(Catalina) 开始,不再支持 32 位系统。 Go 继续对 64 位的 darwin/amd64
平台保持支持。
Go 1.14 可能是最后一个在 iOS,iPadOS,watchOS 和 tvOS(darwin/arm
端口) 上支持 32 位的 Go 版本。 Go 继续保持对这些平台 64 位 darwin/arm64
版本的支持。
Windows
Windows 上的 Go 二进制文件现已启用 DEP(数据执行保护)。
WebAssembly
从 Go 通过 js.Value
对象引用的 JavaScript 值现在支持垃圾收集。
js.Value
值不再使用 ==
运算符进行比较,而必须使用其 Equal
方法进行比较。
js.Value
现在具有 IsUndefined
,IsNull
和IsNaN
方法。
RISC-V
GO 1.14 包含对 Linux 上 64 位 RISC-V 的实验支持(Goos=Linux
,GOARCH=riscv64
)。需要注意的是,性能、程序集语法稳定性和准确性仍在改进中。
FreeBSD
Go 现在支持 FreeBSD 12.0 或更高版本上的 64 位 ARM 架构(freebsd/arm64
)。
Native Client (NaCl)
正如 Go 1.13 更新日志所公告的,Go 1.14取消了对 Native Client 平台的支持(GOOS=nacl
)。
Illumos
Go 运行时现在会遵循区域 CPU 上限(zone.cpu-cap
资源控制)runtime.NumCPU
和默认值 GOMAXPROCS
的设置。
工具
Go 命令
Vendor
当主模块包含顶级 vendor
目录且其 go.mod
文件指定 go``1.14
或更高版本时,go
命令现在默认为-mod=vendor
。该标志的新值 -mod=mod
使 go
命令改为从模块缓存中加载模块(如不存在vendor
目录时)。
当设置 -mod=vendor
时(显式或默认设置),go
命令现在验证主模块的 vendor/modules.txt
文件与其go.mod
文件是否一致。
go
list
-m
不再无提示地忽略在 vendor
目录中不提供包的可传递依赖项。如果设置了-mod=vendor
并且请求了 vendor/modules.txt
中未提及的模块的信息,那么现在会显示失败。
标志
go get
命令不再接受 -mod
标志。以前,标记的设置要么 被忽略要么 导致构建失败。
当go.mod
文件为只读且不存在顶级vendor
目录时,默认情况下设置-mod = readonly
。
-modcacherw
是一个新标志,它指示 go
命令以默认权限创建的模块目录,而不是只读状态。使用此标志允许测试或其他工具更有可能意外添加未包含在模块的文件。但是,它允许使用rm -rf
(而不是go clean -modcache
)删除模块缓存。
-modfile=file
是一个新标记,它指示go
命令读取(并可能写入) 指定的go.mod
文件。为了确定模块的根目录,仍必须存在一个名为 go.mod
的文件,但该文件不会被访问。当指定 -modfile
时,还将使用备用的 go.sum
文件:其路径是通过从 -modfile
标志派生的,方法是修剪.mod
扩展名并附加.sum
。
环境变量
GOINSECURE
是一个新的环境变量,可指示go
命令在直接从某些源中获取模块时不需要 HTTPS 连接并跳过证书验证。像现有的 GOPRIVATE
变量一样,GOINSECURE
的值是逗号分隔的 glob 模式列表。
Commands outside modules(模块外的命令)
当显示启用模块感知(module-aware)模式时 (通过设置 GO111MODULE=on
), 如果不存在go.mod
文件,大多数模块命令的功能将受到更多限制。例如,go
build
,go
run
,和其他构建命令只能构建标准库中的包和命令行中指定为.go
文件的包。
以前,go
命令会将每个包路径解析为模块的最新版本,但不会记录模块的路径或版本。这导致缓慢的,不可复制的构建。
go
get
继续像以前一样工作,带有显式版本的go
mod
download
和 go
list
-m
也一样。
+incompatible
versions(+不兼容的
版本们)
如果模块的最新版本包含go.mod
文件,则go
get
将不再升级到该模块不兼容的主要版本,除非明确要求或者已经要求该版本。当直接从版本控制中获取时,go
list
也忽略了该模块不兼容的主要版本,但是如果是由代理报告,则可能包括这些版本。
go.mod
文件维护
除了 go
mod
tidy
以外的go
命令不再删除指定间接版本的require
指令,主模块的其他(传递)依赖项已经隐含了这种依赖关系。
当修改只是为了更好看时,除了go
mod
tidy
之外的go
命令不再编辑go.mod
文件。
设置-mod = readonly
时,由于缺少go
指令或一个错误的// indirect
注释,go
命令将不再失败。
模块下载
go
命令现在支持模块模式下的Subversion仓库。
go
命令现在包括来自模块代理和其他HTTP服务器的纯文本错误消息的片段。只有当错误消息是有效的UTF-8,并且仅包含图形字符和空格时,它才会显示。
测试
go test -v
现在可以当t.Log
一开始就流式传输它的输出,而不是在所有测试结束时进行输出。
运行时
此版本提高了defer
的大多数用法的性能,与直接调用deferred函数相比,开销几乎为0。因此,defer
现在可以在对性能至关重要的代码中使用,而无需担心开销。
Goroutine现在可以异步抢占。因此,在goroutine中写死循环也不再可能使调度程序死锁,或显著延迟垃圾回收。除windows/arm
,darwin/arm
,js/wasm
和plan9/*
之外的所有平台均支持此功能。
实施抢占的结果是,在包括Linux和macOS系统在内的Unix系统上,使用Go1.14构建的程序将比使用早期版本构建的程序接收更多的信号。这意味着程序使用诸如syscall
或者 golang.org/x/sys/unix
包的将看到更多缓慢的系统调用失败,并出现EINTR
错误。这些程序将必须以某种方式处理这些错误,最有可能的是循环的再次尝试系统调用。有关此的更多信息,请参阅Linux系统的man 7 signal
或其他系统的类似文档。
页面分配器效率更高,并且在GOMAXPROCS
的值很高时引发锁的争用显著减少。因为大额的分配被并行和高速的处理,延迟时间较短并且吞吐量较高最为显著。
内部计时器,由time.After
, time.Tick
, net.Conn.SetDeadline
使用,和其他一些朋友使用,效率更高了,花费更少锁定争用和较少的上下文切换。这是一项不会引起任何用户可见改变的性能改进。
Compiler(编译器)
此版本添加了-d=checkptr
作为编译时选项,用于添加检测以检查 Go 代码是否动态地遵循unsafe.Pointer
的安全准则。默认情况下,此选项通过-race
或-msan
参数启用(除了在Windows上),并且可以通过 -gcflags=all=-d=checkptr=0
禁用。具体来说,-d=checkptr
会检查以下内容:
当转换
unsafe.Pointer
成*T
时,结果指针必须与T
适当对齐如果指针运算的结果指向一个 Go 的堆对象,其中一个不安全指针类型(unsafe.Pointer-typed)的操作数必须指向同一个对象。
目前不建议在Windows上使用-d=checkptr
,因为它会在标准库中导致错误警告。
编译器现在可以使用-json
标志发出机器可读的关键优化日志,包括对内联、逃逸分析、边界范围检查和 nil 检查的排除。
详细的逃逸分析诊断(-m=2
)现在再次生效。这是从先前版本中新的逃逸分析实现中删除的。
macOS 二进制文件中的所有 Go 符号现在都以下划线开头,遵循平台约定。
该版本包括对编译器插入的模糊化覆盖率工具的实验支持。详见第 issue 14565。该应用编程接口在未来的版本中可能会改变。
边界检查消除现在使用来自切片创建的数据信息,并且可以消除对类型小于int的索引的检查。
Core library(核心库)
New byte sequence hashing package
GO 1.14包含一个新的软件包hash/maphash
,它提供字节序列的散列函数,这些散列函数用于实现需要将任意字符串或字节序列映射到无符号64位整数上的均匀分布的散列表或其他数据结构。
散列函数是防止碰撞的,但不是加密安全的。
给定字节序列的哈希值在单个进程中是一致的,但是在不同的进程中会有所不同。
Minor changes to the library(对库的小改动)
和往常一样,在考虑到Go 1 兼容性 的前提下,对库进行了各种细微的更改和更新。
crypto/tls
对SSL版本3.0 (SSLv3)的支持已被移除。请注意,SSLv3是在TLS之前被密码破解的协议。不能再通过GODEBUG
环境变量禁用TLS 1.3。使用Config.MaxVersion
字段用于配置TLS版本。当通过Config.Certificates
字段提供多个证书链时。首先会自动选择第一个与对等项兼容的字段。例如,这允许提供一个ECDSA和一个RSA证书,并让包自动选择最好的一个。请注意,该选择的性能将会很差,除非Certificate.Leaf
字段已设置。新的CipherSuites
和 InsecureCipherSuites
函数返回当前实现的密码套件列表。新的CipherSuiteName
函数返回密码套件标识的名称。新的(*ClientHelloInfo).SupportsCertificate
和(*CertificateRequestInfo).SupportsCertificate
方法暴露了对等方是否支持某个证书。tls包不再支持传统的下一个协议协商(NPN)扩展,现在只支持ALPN。在以前的版本中,它支持两者。没有API更改,应用程序应该像以前一样运行。大多数其他客户端和服务器已经取消了对NPN的支持,转而支持标准化的ALPN。现在,当在TLS 1.2握手中得到支持时,就可以使用RSA-PSS签名。这不会影响大多数应用程序,但自定义证书Certificate.PrivateKey
不支持RSA-PSS签名的私有密钥实现将需要使用新的Certificate.SupportedSignatureAlgorithms
字段禁用它们。如果设置了 Config.GetConfigForClient
,Config.Certificates
和Config.GetCertificate
会置为空。如果回调既不返回证书也不返回错误,则现在发送unrecognized_name
。新CertificateRequestInfo.Version
字段会在客户端证书的回调里返回TLS版本。新的TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
和TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
常量使用之前称为TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
和 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
的密码套件的最终名称。
crypto/x509
Certificate.CreateCRL
现在支持Ed25519发行者。
debug/dwarf
debug/dwarf
包现在支持读取DWARF 版本5。新方法(*Data).AddSection
支持从输入文件向DWARF数据添加任意新的DWARF部分。新方法 (*Reader).ByteOrder
返回当前编译单元的字节顺序。这可用于解释以本机顺序编码的属性,例如位置描述。新方法 (*LineReader).Files
从行阅读器返回文件名表。这可以用来解释DWARF属性的值,例如AttrDeclFile。
encoding/asn1
Unmarshal
现在支持ASN.1字符串类型BMPString,由新的 TagBMPString
常量表示。
encoding/json
Decoder
类型支持一种新的方法 InputOffset
,该方法返回当前decoder位置的输入流的字节偏移量。Compact
不再转义 U+2028
和U+2029
字符,这一直都不是一个可以文档化的特性。有关正确的转义,请参见HTMLEscape
。Number
不再接受无效的数字,以便更紧密地跟踪记录的行为。如果程序需要接受像空字符串这样的无效数字,可以考虑用 Unmarshaler
来包装类型。
go/build
Context
类型有一个新的字段Dir
,可以用来设置编译的工作目录。默认值是正在运行的进程的当前目录。在Module模式下,这主要用于找出主Module的路径。
go/doc
新函数NewFromFiles
会根据*ast.File
的列表和与包元素类似的相关联的例子计算包内容,在 Package
, Type
, 和 Func
类型和新的Suffix
参数在Example
类型中新的Examples
参数是可用的。
io/ioutil
TempDir
现在可以创建具有前缀和后缀名称的目录。与TempFile
一样,如果模板中包含’‘,则会用随机字符串替换最后一个 ‘‘。
log
新的Lmsgprefix
参数可用于告诉日志函数在日志消息之前,,而不是在行的开头发出可选的输出前缀。
math
新的FMA
函数以浮点形式计算x*y+z
,不需要x*y
计算的中间舍入。有些架构使用专用硬件指令来实现这种计算,以提高性能。
math/big
GCD
方法现在允许输入a和b可以为零或为负。
math/bits
新函数 Rem
, Rem32
, 和 Rem64
支持计算余数,即使商溢出也是如此。
mime
.js和.mjs文件的默认类型现在是text/javascript
,而不是application/javascript
。这与 an IETF draft将application/javascript
视为过时的草案是一致的。
mime/multipart
新的 Reader
方法NextRawPart
支持提取下一个MIME部分,而无需透明地解码quoted-printable
数据。
net/http
新的方法Header
的 Values
可用于获取与标准化的key相关联的所有值。新的 Transport
类型的字段DialTLSContext
可用于指定可选的dial
函数为非代理的HTTPS请求创建TLS连接。这个新字段可以用来代替现在准备遗弃的 DialTLS
;DialTLS
将会继续使用,但是新的代码应该使用 DialTLSContext
,这样一旦不再需要,传输就可以取消dials。在Windows上,ServeFile
现在可以支持大于2GB的文件。
net/http/httptest
新的Server
类型的字段EnableHTTP2
支持在测试服务器上启用HTTP/2。
net/textproto
新的MIMEHeader
方法的Values
可用于获取与标准化的key相关联的所有值。
os/signal
在Windows上,CTRL_CLOSE_EVENT、CTRL _ CLOSE _ EVENT
和CTRL_SHUTDOWN_EVENT
事件现在支持生成一个(syscall.SIGTERM
)信号,类似于Control-C和Control-Break如何产生syscall.SIGINT
信号。
plugin
plugin
包现在支持 freebsd/amd64
。
reflect
通过在StructField
元素中设置PkgPath
字段, StructOf
可以创建具有未导出字段的struct类型。
runtime
runtime.Goexit
不能再因递归panic/recover
而中止。在macOS上,在初始化Go runtime之前,SIGPIPE
不再转发给已安装的信号处理程序。这是必要的,因为macOS将SIGPIPE
传递给主线程,而不是将线程写入关闭的管道中。
runtime/pprof
生成的profile文件不再包括用于内联标记的pseudo-PCs。内联函数的符号信息以pprof工具希望的格式编码。这是针对最近版本中引入的回归的修复程序。
strconv
NumError
类型现在有一个Unwrap
方法,可以用来检索转换失败的原因。这支持使用errors.Is
方法的NumError
值判断是否是潜在的错误:strconv.ErrRange
或 strconv.ErrSyntax
。
sync
解锁一个高度竞争的Mutex
现在直接让CPU交给下一个等待这个Mutex
的goroutine。这大大提升了高CPU数在计算机上高度竞争Mutex
的性能。
testing
testing包现在支持cleanup函数,在测试或基准测试完成后调用,会分别调用T.Cleanup
或B.Cleanup
。
text/template
当带圆括号的参数用作函数时,text/template包现在可以正确地报告错误。这通常出现在错误的情况下,如 {{if (eq .F "a") or (eq .F "b")}}
。这应该写成{{if or (eq .F "a") (eq .F "b")}}
。错误的情况从来没有像预期的那样工作,现在将报告一个错误can't give argument to non-function
不能给非函数的参数。
unicode
整个系统的unicode
包和相关支持已从Unicode 11.0升级到Unicode 12.0,增加了554个新字符,包括4个新脚本和61个新表情符号。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: