GO 1.15-发行说明草案

2020-06-12 09:59:36

Go 1.15尚未发布。这些是正在进行的发行说明。Go 1.15预计将于2020年8月发布。

正如GO 1.14发行说明中宣布的那样,GO 1.15现在需要MacOS 10.12 Sierra或更高版本;对以前版本的支持已经停止。

正如GO 1.14发行说明中宣布的那样,GO 1.15在MacOS、iOS、iPadOS、watchOS和twOS(Darwin/386和Darwin/ARM端口)上取消了对32位二进制文件的支持。Go继续支持64位Darwin/AMD64和Darwin/arm64端口。

GO 1.15现在在提供-buildmode=PIE cmd/link标志时生成Windows ASLR可执行文件。在Windows上,GO命令默认使用-buildmode=Pie。

现在,-race和-msan标志始终启用-d=checkptr,这将检查unsafe.Pointer的使用情况。以前,除Windows之外的所有操作系统都是这种情况。

GO构建的DLL不再导致进程在收到信号(如终端上的Ctrl-C)时退出。

当链接Android的二进制文件时,Go 1.15会显式选择NDK的最新版本中可用的LLD链接器。LLD链接器避免了某些设备上的崩溃,并计划在未来的NDK版本中成为默认的NDK链接器。

GO 1.15在GOARCH=ARM和GOARCH=arm64上添加了对OpenBSD 6.7的支持。以前版本的Go已经在GOARCH=386和GOARCH=AMD64上支持OpenBSD 6.7。

在改进Linux(GOOS=Linux,GOARCH=riscv64)上64位RISC-V端口的稳定性和性能方面取得了进展。它现在还支持异步抢占。

GOPROXY环境变量现在支持跳过返回错误的代理。代理URL现在可以用逗号(,)或竖线字符(|)分隔。如果代理URL后跟逗号,则GO命令将仅在404或410 HTTP响应之后尝试列表中的下一个代理。如果代理URL后跟管道字符,则GO命令将在出现任何错误后尝试列表中的下一个代理。请注意,GOPROXY的默认值仍然是https://proxy.golang.org,DIRECT,在出现错误时不会回退到DIRECT。

更改-timeout标志现在会使缓存的测试结果无效。当使用较短的超时重新调用GO测试时,超时较长的测试运行的缓存结果将不再被视为通过。

GO TEST和GO VET中的各种标志解析问题已修复。值得注意的是,GOFLAGS中指定的标志得到了更一致的处理,并且-outputdir标志现在解释相对于go命令的工作目录(而不是每个单独测试的工作目录)的相对路径。

现在可以使用GOMODCACHE环境变量设置模块缓存的位置。GOMODCACHE的默认值是GOPATH[0]/pkg/mod,这是此更改之前模块缓存的位置。

现在有一种解决方法可用于Windows";访问被拒绝";访问模块缓存的GO命令中的错误,这些错误是由外部程序并发扫描文件系统引起的(请参见问题#36568)。默认情况下未启用解决方法,因为当低于1.14.2和1.13.10的GO版本与同一模块缓存同时运行时,使用该解决方法是不安全的。可以通过明确设置环境变量GODEBUG=modcacheunzipinplace=1来启用它。

VET工具现在警告格式字符串(X)的转换,其中x的整数类型不是rune或byte。使用围棋的经验表明,这种形式的许多转换错误地假设字符串(X)的计算结果为整数x的字符串表示形式。实际上,它的计算结果是包含x值的Utf-8编码的字符串。例如,字符串(9786)的计算结果不是字符串";\xe2\x98\xba";或";☺";。

正确使用字符串(X)的代码可以重写为字符串(rune(X))。或者,在某些情况下,使用合适的字节片buf调用utf8.EncodeRune(buf,x)可能是正确的解决方案。其他代码最有可能使用strtru.itoa或fmt.Sprint。

我们正在考虑在未来的围棋版本中禁止转换。也就是说,当x的类型为RUNE或BYTE时,语言将更改为仅允许整数x的字符串(X)。这样的语言更改不会向后兼容。我们用这次兽医检查作为改变语言的第一步。

当类型断言总是失败时,VET工具现在会就从一种接口类型到另一种接口类型的类型断言发出警告。如果两种接口类型实现同名但类型签名不同的方法,则会发生这种情况。

没有理由编写总是失败的类型断言,因此任何触发此VET检查的代码都应该重写。

我们正在考虑在GO的未来版本中禁止不可能的接口类型断言。这样的语言更改不会向后兼容。我们用这次兽医检查作为改变语言的第一步。

如果使用其类型派生自以下任一值的值调用Panic:bool、Complex 64、Complex 128、float32、float64、int、int8、int16、int32、int64、string、uint、uint8、uint16、uint32、uint64、uintptr,则将打印该值,而不仅仅是其地址。以前,这只适用于恰好属于这些类型的值。

在Unix系统上,如果KILL命令或KILL系统调用用于向GO程序发送SIGSEGV、SIGBUS或SIGFPE信号,并且如果该信号未通过os/Signal.Notify进行处理,则GO程序现在将可靠地崩溃并跟踪堆栈。在早期版本中,该行为是不可预测的。

现在,小对象的分配在内核数量高的情况下执行得更好,并且具有更低的最坏情况延迟。

关闭信道上的非阻塞接收现在的性能与开放信道上的非阻塞接收一样。

包不安全的安全规则允许在调用某些函数时将不安全的指针转换为uintptr。以前,在某些情况下,编译器允许多个链式转换(例如,Syscall.Syscall(…。,uintptr(uintptr(Ptr)),…)。。编译器现在只需要一个转换。应更新使用多个转换的代码以满足安全规则。

与Go 1.14相比,Go 1.15通过消除某些类型的GC元数据并更积极地消除未使用的类型元数据,将典型的二进制大小减少了约5%。

工具链现在通过将函数与32字节边界对齐并填充跳转指令来减轻GOARCH=AMD64上的英特尔CPU勘误表SKX102。虽然此填充增加了二进制大小,但上面提到的二进制大小改进足以弥补这一点。

Go 1.15向编译器和汇编器都添加了-specte标志,以允许启用Spectre缓解。这些几乎不应该是需要的,主要是作为一种“纵深防御”机制来提供的。有关详细信息,请参阅Spectre维基页面。

编译器现在拒绝对其应用的声明没有意义的//go:编译器指令,并显示错误的";放错位置的编译器指令。这种错误应用的指令以前被破坏过,但是被编译器悄悄地忽略了。

编译器s-json优化日志记录现在报告大型(>;=128字节)副本,并包括对转义分析决策的解释。

此版本对GO链接器进行了实质性改进,减少了链接器资源的使用(时间和内存),并提高了代码的健壮性/可维护性。

对于一组具有代表性的大型围棋程序,对于在AMD64架构上运行的基于ELF的操作系统,链接速度加快了20%,平均需要的内存减少了30%,而对于其他架构/操作系统组合,改进更为温和。

提高链接器性能的关键因素是最新重新设计的目标文件格式,以及内部阶段的改进以提高并发性(例如,并行地对符号应用重新定位)。GO 1.15中的目标文件比其1.14等效项稍大。

这些更改是更新Go链接器的多版本项目的一部分,这意味着在未来的版本中将会有更多的链接器改进。

Go 1.15包含一个新的包,time/tzdata,它允许将时区数据库嵌入到程序中。即使本地系统上的时区数据库不可用,导入此软件包(作为import_";time/tzdata";)也允许程序查找时区信息。您还可以通过构建带有-tag的timetzdata来嵌入时区数据库。这两种方法都会使程序的大小增加约800KB。

Go 1.15将把C类型的EGLConfig转换为Go类型的uintptr。这一变化类似于Go 1.12及更新版本对EGLDisplay、Darwin的CoreFoundation和Java的JNI类型的处理方式。有关详细信息,请参阅CGO文档。

与往常一样,库有各种微小的更改和更新,这些更改和更新都考虑到了兼容性的Go 1承诺。

该软件包现在定义了PE文件格式使用的IMAGE_FILE、IMAGE_SUBSYSTEM和IMAGE_DLLCHARACTERISTICS常量。

crypto/rsa、crypto/ecdsa和crypto/ed25519包中的PrivateKey和PublicKey类型现在有了一个EQUAL方法来比较密钥的等价性或为公钥建立类型安全接口。方法签名与Go-CMP的相等定义兼容。

新的SignASN1和VerifyASN1函数允许以标准ASN.1 DER编码生成和验证ECDSA签名。

新的MarshalCompresded和UnmarshalCompresded函数允许以压缩格式对NIST椭圆曲线点进行编码和解码。

新的Dialer类型及其DialContext方法允许使用上下文连接TLS服务器并与其握手。

Config类型的新VerifyConnection回调允许为每个连接自定义验证逻辑。它可以访问ConnectionState,其中包括对等证书、SCT和装订的OCSP响应。

自动生成的会话票证密钥现在每24小时自动轮换一次,有效期为7天,以限制其对向前保密的影响。

在TLS 1.2和更早版本中,会话密钥重复用于恢复的连接的会话票证生存期现在被限制为7天,这也是为了限制它们对转发保密性的影响。

RFC 8446中指定的客户端降级保护检查现已实施。这可能会导致客户端遇到行为类似于未经授权的降级攻击的中间盒时出现连接错误。

如果证书上的名称或正在验证的名称(使用VerifyOptions.DNSName或VerifyHostname)无效,现在将不区分大小写进行比较,而不进行进一步处理(不使用通配符或去除尾随点)。无效名称包括包含字母、数字、连字符和下划线以外的任何字符的名称、标签为空的名称以及证书上带有尾随圆点的名称。

现在,默认情况下禁用了在不存在主题替代名称时将CommonName字段视为主机名的过时传统行为。可以通过向GODEBUG环境变量添加值x509IGNORRECN=0来临时重新启用它。如果公用名是无效的主机名,则始终忽略它。

新的CreateRevocationList函数和RevocationList类型允许创建符合RFC 5280的X.509 v2证书吊销列表。

如果模板是CA并且没有显式指定,CreateCertificate现在会自动生成SubjectKeyId。

如果模板指定MaxPathLen但不是CA,CreateCertificate现在会返回错误。

在MacOS以外的Unix系统上,SSL_CERT_DIR环境变量现在可以是冒号分隔的列表。

在MacOS上,无论CGO是否可用,二进制文件现在始终链接到Security.framework以提取系统信任根。产生的行为应该与操作系统验证器更一致。

按照包文档中已经说明的规则,将JSON数组解码为片不再重用任何现有片元素。

解码时引入最大嵌套深度的内部限制。这降低了深度嵌套的输入使用大量堆栈内存的可能性,甚至导致Goroutine堆栈超出限制的可能性。

编码器总是小心翼翼地避免使用XML开头的名称空间前缀,XML规范保留了这些前缀。现在,更严格地遵循规范,该检查不区分大小写,因此也避免了以XML、XML等开头的前缀。

当FLAG包看到-h或-help,并且没有定义这些标志时,FLAG包将打印用法消息。如果FlagSet是使用ExitOnError创建的,则FlagSet.Parse将以状态2退出。在此版本中,-h或-help的退出状态已更改为0。特别是,这适用于命令行标志的默认处理。

TempDir和TempFile现在拒绝包含路径分隔符的模式。也就是说,诸如ioutil.TempFile(";/tmp";,";../base*";)之类的调用将不再成功。这可以防止意外的目录遍历。

如果I/O操作超过Conn.SetDeadline、Conn.SetReadDeadline或Conn.SetWriteDeadline方法设置的截止日期,它现在将返回一个错误,该错误是或包装os.ErrDeadlineExceed。这可用于可靠地检测错误是否由于超过最后期限而引起。早期版本建议对错误调用Timeout方法,但是I/O操作可能会返回错误,即使没有超过期限,超时也会返回TRUE。

新的Resolver.LookupIP方法支持特定于网络并接受上下文的IP查找。

作为对抗请求走私攻击的强化措施,解析现在变得更加严格:不再像SP和HTAB那样修剪非ASCII空格,并且不再支持传输编码(";Identity";Transfer-Encoding)。

ReverseProxy现在支持在该字段的传入Request.Header映射条目为空时不修改X-Forwarded-For标头。

当ReverseProxy处理的交换协议(如WebSocket)请求被取消时,后端连接现在可以正确关闭。

所有配置文件端点现在都支持";秒";参数。如果存在,端点将分析指定秒数并报告差异。CPU配置文件和跟踪端点中的";秒";参数的含义没有改变。

新的URL字段RawFragment和方法EscapedFragment提供关于特定片段的确切编码的详细信息并对其进行控制。它们类似于RawPath和EscapedPath。

新的URL方法redated以字符串形式返回URL,并将所有密码替换为xxxxx。

如果I/O操作超过了File.SetDeadline、File.SetReadDeadline或File.SetWriteDeadline方法设置的截止日期,它现在将返回一个错误,该错误是或包装os.ErrDeadlineExceed。这可用于可靠地检测错误是否由于超过最后期限而引起。早期版本建议对错误调用Timeout方法,但是I/O操作可能会返回错误,即使没有超过期限,超时也会返回TRUE。

软件包os和net现在会自动重试使用EINTR失败的系统调用。以前,这会导致虚假故障,随着异步抢占功能的增加,这种情况在GO 1.14中变得更加常见。现在这件事被透明地处理了。

Package Reflect现在不允许访问所有未导出字段的方法,而以前它允许访问未导出的嵌入字段的方法。依赖于先前行为的代码应更新为访问封闭变量的相应提升方法。

新的Regexp.SubexpIndex方法返回正则表达式中具有给定名称的第一个子表达式的索引。

FormatComplex将复数转换为(a+bi)形式的字符串,其中a和b是实部和虚部。

ParseComplex将字符串转换为指定精度的复数。ParseComplex接受N+Ni格式的复数。

新方法Map.LoadAndDelete原子地删除一个键,并返回先前的值(如果存在)。

在Unix系统上,使用SysProcAttr的函数现在将拒绝同时设置Setctty和前台字段的尝试,因为它们都使用Ctty字段,但以不兼容的方式进行设置。我们预计很少有现有的程序集两个字段于一身。

设置Setctty字段现在要求将Ctty字段设置为由ProcAttr.Files字段确定的子进程中的文件描述符编号。使用子描述符总是有效的,但在某些情况下,使用父文件描述符也是有效的。某些设置Setctty的程序需要更改Ctty的值才能使用子描述符编号。

现在可以在WINDOWS/AMD64上调用返回浮点值的系统调用。

Testing.T类型现在有一个Deadline方法,该方法报告测试二进制文件超过其超时的时间。

调用os.Exit不再需要TestMain函数。如果TestMain函数返回,则测试二进制文件将使用m.Run返回的值调用os.Exit。

新方法T.TempDir和B.TempDir返回在测试结束时自动清理的临时目录。