go 1.16简介
最新的Go版本1.16在Go 1.15 6个月后发布。它的大多数更改都是在工具链、运行时和库的实现中进行的。和往常一样,这个版本保持了Go 1对兼容性的承诺。我们希望几乎所有的Go程序都能像以前一样继续编译和运行
语言变更
语言没有变化
工具类
go test
当使用 os.Exit(0) 会被认定为测试失败
Runtime
调整切片扩容策略
Go1.16 以前的 slice 的扩容条件是 len,在最新的代码中,已经改为了以 cap 属性作为基准:
// src/runtime/slice.goif cap > doublecap {newcap = cap} else {// 这是以前的代码:if old.len < 1024 {// 下面是 Go1.16rc1 的代码if old.cap < 1024 {newcap = doublecap}
以官方的 test case 为例:
func main() {const N = 1024var a [N]intx := cap(append(a[:N-1:N], 9, 9))y := cap(append(a[:N:N], 9))println(cap(x), cap(y))}
在 Go1.16 以前输出 2048, 1280。在 Go1.16 及以后输出 1280, 1280,保证了两种的一致
核心库
废弃 io/ioutil
Go 官方认为 io/ioutil 这个包的定义不明确且难以理解。所以 Russ Cox 在 2020.10.17 提出了废弃 io/ioutil 的提案。
大致变更如下:
- Discard => io.Discard
- NopCloser => io.NopCloser
- ReadAll => io.ReadAll
- ReadDir => os.ReadDir
- ReadFile => os.ReadFile
- TempDir => os.MkdirTemp
- TempFile => os.CreateTemp
- WriteFile => os.WriteFile
与此同时大家也不需要担心存在破坏性变更,因为有 Go1 兼容性的保证,在 Go1 中 io/ioutil 还会存在,只变更内部的方法调用:
func ReadAll(r io.Reader) ([]byte, error) {return io.ReadAll(r)}func ReadFile(filename string) ([]byte, error) {return os.ReadFile(filename)}
支持静态资源嵌入
import _ "embed"//go:embed hello.txtvar s stringprint(s)
新增 io/fs 的支持
新增了标准库 io/fs,正式将文件系统相关的基础接口抽象到了该标准库中。
以前的话大多是在 os 标准库中,这一步抽离更进一步的抽象了文件树的接口。在后续的版本中,大家可以优先考虑使用 io/fs 标准库。
