Go 1.15 有什么新变化?
一篇关于 Go 1.15 的版本笔记,重点放在链接器、运行时成本和标准库的小而实用的变化。
扫码在手机上阅读。
Go 1.15 发布于 2020 年 8 月 11 日。它不是那种让人立刻重写服务的版本,更像一次安静的维护:链接、运行时、二进制体积和标准库细节都变得更顺手一点。1注 1Go 1.15 的主要版本说明。
工具链改进.
Go 1.15 最值得关注的变化之一是链接器重写。官方说明提到,更快的链接速度、更低的内存占用,以及用 Go 实现的新基础,为后续工具链工作留下了更清晰的空间。2注 2Go 团队对发布重点的解释。
我会把这类升级记录成很短的仓库笔记:
go version
go test ./...
go test -race ./...
go build -trimpath ./cmd/service好的升级记录不需要复杂,关键是能复查:从哪个版本到哪个版本,构建时间有没有变化,二进制体积有没有变化,是否出现了代码层面的兼容调整。
运行时成本.
defer 在 Go 1.15 里有了实用的性能改进。常见场景下,运行时可以使用 open-coded defers,让清理型代码保留清晰写法的同时减少成本。
func processFile(filename string) error {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
return process(f)
}这件事的意义不是鼓励到处写 defer,而是让普通代码不用为了微小成本过早变形。真正的规则仍然是:
- 01让
defer出现在能表达资源归属的位置。 - 02先用 profile 找到热点路径。
- 03不要在没有证据时牺牲可读性。
标准库细节.
time/tzdata 让程序可以把时区数据库嵌入二进制文件。对小容器、受限系统或宿主环境不可靠的部署来说,这个选择能减少外部依赖。3注 3适合部署环境不稳定或缺少 zoneinfo 的场景。
package main
import (
"fmt"
"time"
_ "time/tzdata"
)
func main() {
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
panic(err)
}
fmt.Println(time.Now().In(loc).Format(time.RFC3339))
}测试里也有一个小但有用的 API:testing.TB.TempDir。它给测试提供自动清理的临时目录,减少共享路径和手写 cleanup 带来的噪音。
func TestSomething(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "sample.txt")
if err := os.WriteFile(path, []byte("hello"), 0o644); err != nil {
t.Fatal(err)
}
}升级判断.
Go 1.15 是一次保守发布,但保守不等于无感。评估升级时,我会看三类信号:
| 范围 | 观察内容 | 常见信号 |
|---|---|---|
| 工具链 | build、link、vet、race | CI 时间和峰值内存 |
| 运行时 | defer、分配密集路径 | profile 变化 |
| 环境 | 时区文件、容器、测试目录 | 只在部署环境出现的问题 |
这类版本最好的结果是无事发生:服务照常运行,CI 更快一点,制品更小一点,部署假设更少一点。
— 讨论
GitHub评论.
评论由 GitHub Discussions 承载。请围绕文章内容交流,并保持克制、友善。
评论暂时没有加载出来。可以稍后刷新重试,或直接到 GitHub Discussions 参与讨论。