Go 1.15 正式发布
共 3964字,需浏览 8分钟
·
2020-08-14 14:12
就在昨天,也就是2020年8月11日,go开发团队发布了go最新版本1.15。该版本在 1.14 的基础上继续改进工具链、运行时和库。也保留了GO1兼容性的承诺。这几乎保证所有的go程序都能像以前那样的正常编译与运行。并且在Go 1.15中对链接器也有重大改进,改进了对具有大量内核的小对象的分配,并弃用了 X.509 CommonName。GOPROXY 现在支持跳过返回错误的代理,并添加了新的嵌入式 tzdata 包。
编译器
包 unsafe
的安全规则允许在调用某些函数时将 unsafe.Pointer
转换为uintptr
。以前,在某些情况下,编译器允许进行多次链接转换(例如 syscall.Syscall(…uintptr(uintptr(ptr)), …)
)。现在,编译器只需要一次转换。使用多次转换的代码应进行更新以满足安全规则。与 Go 1.14 相比,Go 1.15 通过消除某些类型的 GC 元数据并更积极地消除了未使用的类型元数据,与 Go 1.14 相比将典型的二进制大小减少了大约5%。该工具链现在通过将函数与 32 字节边界对齐并填充跳转指令来缓解 GOARCH=amd64 上的 Intel CPU 勘误 SKX102 。尽管此填充增加了二进制大小,但这远远超出了上述二进制大小改进所弥补的范围。Go 1.15在编译器和汇编器中都添加了一个标志-spectre
,以允许启用 Spectre 缓解措施。这些几乎永远都不需要,主要是作为“纵深防御”机制提供的。现在,编译器将拒绝 //go:compiler
指令,这些指令对其所使用的声明无意义,并出现“放错位置的编译器指令”错误。此类错误使用的指令以前已被破坏,但编译器无声地忽略了它们。编译器的 -json
优化日志现在报告大(> = 128字节)副本,并包含转义分析决策的说明。
链接器
此版本对 Go 链接器进行了重大改进,可减少链接器资源的使用(时间和内存)并提高代码的健壮性/可维护性。对于ELF
在amd64
体系结构上运行的基于OS(Linux,FreeBSD,NetBSD,OpenBSD,Dragonfly 和 Solaris)的操作系统,代表性的大型 Go 程序集的链接速度提高20%,平均所需内存减少30%,对其他架构/OS 组合也进行了适度的改进。改进链接程序性能的关键因素是新设计的目标文件格式,以及内部阶段的改进以提高并发性(例如,将重定位并行应用于符号)。Go 1.15中的目标文件比其1.14等价文件稍大。这些更改是对Go链接器进行现代化改造的多版本项目的一部分,这意味着将来的版本中有望对链接器进行其他改进。现在,链接器在 linux/amd64 和 linux/arm64 上默认为 -buildmode=pie
的内部链接模式,因此这些配置不再需要 C 链接器。
运行时
如果使用的值源自以下任何一个类型来调用 panic :bool
,complex64
,complex128
,float32
,float64
, int
,int8
,int16
,int32
,int64
,string
, uint
,uint8
,uint16
,uint32
,uint64
,uintptr
,则该值将被打印,而不是仅仅其地址。以前,仅对于这些类型的值才适用。在 Unix 系统上,如果使用kill命令或kill系统调用将 SIGSEGV , SIGBUS 或 SIGFPE 信号发送到 Go 程序,并且如果该信号未通过 [os/signal.Notify](https://golang.org/pkg/os/signal/#Notify)
处理,Go 程序将通过堆栈跟踪可靠地崩溃。在早期版本中,这种行为是无法预测的。小对象的分配现在在高内核数下表现更好,并且最坏情况下的延迟也更低。将小整数值转换为接口值不再导致分配。现在,关闭通道上的非阻塞接收与打开通道上的非阻塞接收一样有效。
工具类
Go 命令
GOPROXY
现在 ,环境变量支持跳过返回错误的代理。代理URL现在可以用逗号(,
)或竖线字符(|
)分隔。如果代理URL后面带有逗号,则该go
命令将仅在404或410 HTTP响应后尝试列表中的下一个代理。如果代理URL后面带有竖线字符,该go
命令将在出现任何错误后尝试列表中的下一个代理。请注意,默认值GOPROXY
keeps [https://proxy.golang.org,direct](https://proxy.golang.org,direct)
,在出现错误时不会退回到 Direct 。
Go test
更改 -timeout
标志会使缓存的测试结果无效。当使用短超时重新调用 Go 测试时,具有长超时的测试运行的缓存结果将不再被视为通过。
标记解析
修复了go tes
t和go vet
中的各种标志解析问题。值得注意的是,GOFLAGS 中指定的标志得到了更一致的处理,并且-outputdir
标志现在解释了相对于go
命令的工作目录(而不是每个测试的工作目录)的相对路径。
标记解析
现在可以使用GOMODCACHE
环境变量设置模块缓存的位置。GOMODCACHE 的默认值为 GOPATH [0] / pkg / mod,这是此更改之前模块缓存的位置。由于外部程序同时扫描文件系统而导致访问模块缓存的命令中出现“访问被拒绝”错误,目前有一个 Windows 环境下的解决方案。(详情可见 issue #36568)这个解决方案在默认情况下是不启用的,因为当低于1.14.2和1.13.10的Go版本与相同的模块缓存并发运行时,使用它是不安全的。可以通过显式设置环境变量 GODEBUG=modcacheunzipinplace=1 来启用它。
核心库
新的嵌入式 tzdata 包
Go 1.15添加一个新 [time/tzdata](https://golang.org/pkg/time/tzdata/)
包,该包允许将时区数据库嵌入程序中。导入该软件包(如import _ "time/tzdata"
)可以使程序找到时区信息,即使本地系统上不存在时区数据库,该程序也可以查找时区信息。您还可以通过使用 -tags timetzdata
嵌入时区数据库。两种方法都会使程序的大小增加大约800 KB。
X.509 CommonName弃用
默认情况下,将X.509证书上的 CommonName 字段作为主机名处理(当没有主题替代名称出现时)的行为现在已被禁用。可以通过向 GODEBUG 环境变量添加值 x509ignoreCN=0 来临时重新启用它。请注意,如果CommonName
主机名无效,则无论 GODEBUG
设置如何,都将始终忽略该主机名。无效名称包括那些带有字母,数字,连字符和下划线以外的任何字符的名称,以及带有空标签或结尾点的名称。
database/sql
新的 DB.SetConnMaxIdleTime 方法允许在连接池空闲一段时间后从连接池中删除连接,而不考虑连接的总生命周期。数据库。DBStats.MaxIdleTimeClosed 字段显示由于 DB.SetConnMaxIdleTime 关闭的连接总数。新的 Row.Err getter 允许检查查询错误而不调用 Row.Scan。
crypto/tls
新 Dialer
类型及其 DialContext
方法允许使用上下文与TLS服务器进行连接和握手。Config 类型上新的 VerifyConnection 回调允许为每个连接使用自定义验证逻辑。它可以访问 ConnectionState,其中包括对等证书,SCT和装订的 OCSP 响应。自动生成的会话票证密钥现在每24小时自动旋转一次,生命周期为7天,以限制它们对前向保密性的影响。TLS 1.2 和更早版本中的会话票证生命周期现在限制为7天,其中TLS会话密钥被重新用于恢复的连接,这也限制了它们对前向保密性的影响。现在强制执行RFC 8446中指定的客户端降级保护检查。这可能会导致客户端遇到类似于未授权降级攻击的中间人时出现连接错误。SignatureScheme
, CurveID
和 ClientAuthType
现在实现了 fmt.Stringer
。现在,在客户端恢复的连接上重新填充 ConnectionState 字段的 OCSPResponse 和SignedCertificateTimestamps。tls.Conn 现在在永久断开的连接上返回不透明的错误,并包装了临时的 net.Error 。要访问原始的 net.Error ,请使用 errors.As(或 errors.Unwrap )而不是类型断言。
testing
现在,testing.T 类型具有 Deadline 方法,该方法会报告测试的二进制文件已超过其超时时间多久。不再需要 TestMain 函数来调用 os.Exit 。如果返回 TestMain 函数,则测试二进制文件将使用 m.Run 返回的值调用 os.Exit 。新方法 T.TempDir 和 B.TempDir 返回临时目录,这些目录在测试结束时会自动清除。go test -v
现在按测试名称对输出进行分组,而不是在每行上打印测试名称。
更详细的改动
更多详细的改动,点击“阅读原文”见官方发布文档