Go 1.15 正式发布:看看都有哪些值得关注的变化

polaris · · 5215 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

刚刚 Go Team 宣布 Go 1.15 正式发布。受疫情影响,这次版本变化的内容不太多,但如期发布了。 它的大部分更改在工具链、运行时和库的实现。与往常一样,该版本保留了 Go 1 兼容性的承诺。这几乎保证所有的 Go 程序都能像以前一样正常编译和运行。 Go 1.15 包括对链接器的重大改进,改进了对具有大量内核的小对象的分配,并弃用了 X.509 CommonName。GOPROXY 现在支持跳过返回错误的代理,并添加了新的嵌入式 tzdata 包。 我们一起看看具体都有哪些值得关注的变化。 ## 1、新的链接器 官方的设计文档地址:<https://golang.org/s/better-linker>,从命名看,是一个更好的链接器(这是废话)。 此版本 Go 可减少链接器资源的使用(时间和内存)并提高代码的健壮性/可维护性。对于在 amd64 架构上运行的基于 ELF 的操作系统(Linux,FreeBSD,NetBSD,OpenBSD,Dragonfly 和S olaris),代表性的大型 Go 程序集的链接速度提高 20%,平均所需内存减少 30%。其他体系结构/OS 组合的改进。改进链接程序性能的关键因素是新设计的目标文件格式,以及内部阶段的改进以提高并发性(例如,将重定位并行应用于符号)。Go 1.15 中的目标文件比其 1.14 等价文件稍大。这些更改是对 Go 链接器进行现代化改造的多版本项目的一部分,这意味着将来的版本中有望对链接器进行其他改进。现在,链接器在 linux/amd64和 linux/arm64 上默认为 -buildmode=pie 的内部链接模式,因此这些配置不再需要 C 链接器。 ## 2、编译器改进,包括略微小了些的二进制文件 包 unsafe 的[安全规则](https://golang.org/pkg/unsafe/#Pointer)允许在调用某些函数时将 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](https://www.intel.com/content/www/us/en/support/articles/000055650/processors.html)。尽管此填充增加了二进制大小,但这远远超出了上述二进制大小改进所弥补的范围。 Go 1.15 向编译器和汇编器都添加了 -spectre 标志,以允许启用 Spectre 缓解措施。这些几乎是绝对不需要的,主要是作为“纵深防御”机制提供的。有关详细信息,请参见 [Spectre Wiki页面](https://github.com/golang/go/wiki/Spectre)。 现在,编译器将拒绝 //go: compiler 指令,这些指令对其所使用的声明无意义,并出现“放错位置的编译器指令”错误。此类错误使用的指令以前已被破坏,但编译器无声地忽略了它们。 现在,编译器的 -json 优化日志记录报告大(>= 128 字节)副本,并包含转义分析决策的说明。 ## 3、内嵌 tzdata(时区数据) 增加了一个新包:time/tzdata,当系统找不到时区数据时(比如 Windows 等),通过导入这个包,在程序中内嵌时区数据,也可以通过编译时传递 `-tags timetzdata` 来实现同样的效果。 具体查看这个 issue:<https://github.com/golang/go/issues/38017> 以及包 time/tzdata 的说明:<https://golang.org/pkg/time/tzdata/>。 ## 4、增加 testing.TB.TempDir 测试生成临时文件挺常见的,这个为了更好的解决此问题。详情见 issue:<https://github.com/golang/go/issues/35998>。 ## 5、增加 testing.T.Deadline 将 context 引入 testing 包。详情见 issue:<https://github.com/golang/go/issues/28135>。 ## 6、关于 Ports 部分 darwin/386、darwin/arm 不再支持;riscv64 变得更好;linux/arm64 现在作为第一类 port 支持。 ## 7、API 的变动 1)net/url.URL RawFragment 和 EscapedFragment ,详情见 issue:<https://github.com/golang/go/issues/37776>; 2)net/url.URL.Redacted,详情见 issue:<https://github.com/golang/go/issues/34855>; 3)time.Ticker.Reset,我们知道 Timer 是有 Reset 的,这次为 Ticker 也增加,详情见 issue:<https://github.com/golang/go/issues/33184>; 4)regexp.Regexp.SubexpIndex,详情见 issue:<https://github.com/golang/go/issues/32420>; 5)sync.Map.LoadAndDelete,详情见 issue:<https://github.com/golang/go/issues/33762>; 6)crypto/tls.Dialer.DialContext,详情见 issue:<https://github.com/golang/go/issues/18482>; 还有其他一些 API 变动,不一一列举。 ## 8、工具链 1)增加 go env GOMODCACHE:<https://github.com/golang/go/issues/34527>; 2)opt-in fallbacks in GOPROXY:<https://github.com/golang/go/issues/37367>; 3)vet:warn about string(int) 和 detect impossible interface assertions:<https://github.com/golang/go/issues/32479> 和 <https://github.com/golang/go/issues/4483>; 4)println 允许打印两个值。println(twoValues()); 5)panic:显示可打印的值而不是地址。比如: ```go type MyString string panic(MyString("hello")) ``` 现在打印: ```bash panic: (main.MyString) (0x48aa00,0x4c0840) ``` 期望打印: ```bash panic: main.MyString("hello") ``` 可读性会好很多。 ## 9、性能 1)在 amd64 上更好的写屏蔽; 2)在 Linux 上,forkAndExec 使用 dup3; 3)sha512 算法速度提升 15%; 4)ReadMemStats 延迟降低 95%; 5)关闭状态的 channel 接收速度提升 99%; 6)将小的 int 值转为 interface{} 不额外分配内存; ## 10、更详细的改动 更多详细的改动,见官方发布文档 <https://docs.studygolang.com/doc/go1.15>。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

5215 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传