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.go
if cap > doublecap {
newcap = cap
} else {
// 这是以前的代码:if old.len < 1024 {
// 下面是 Go1.16rc1 的代码
if old.cap < 1024 {
newcap = doublecap
}
以官方的 test case 为例:
func main() {
const N = 1024
var a [N]int
x := 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.txt
var s string
print(s)
新增 io/fs 的支持
新增了标准库 io/fs,正式将文件系统相关的基础接口抽象到了该标准库中。
以前的话大多是在 os
标准库中,这一步抽离更进一步的抽象了文件树的接口。在后续的版本中,大家可以优先考虑使用 io/fs
标准库。