Go1.16 正式发布,如下变动你须要知道

如有任何问题或建议,欢迎及时交流和碰撞。个人公众号是 【脑子进煎鱼了】,GitHub 地址: https://github.com/eddycjy

你们好,我是正在努力学习的煎鱼。ios

在前几天,Go1.16rc1 抢先发布了。结合常规的 28 发布规律,其将会在 2021.02 月份左右发布正式版本。git

image.png

此次 Go1.16 也带来了一些新特性或变动。那么做为一个 Gopher,想必不能错过此次的更新。github

image.png

今天这篇文章将会带你们了解一下 Go1.16 的几个须要关注的特性。golang

废弃 io/ioutil

Go 官方认为 io/ioutil 这个包的定义不明确且难以理解。因此 Russ Cox 在 2020.10.17 提出了废弃 io/ioutil 的提案。json

大体变动以下:微信

  • 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)
}

你们在后续也能够改改调用习惯。架构

支持静态资源嵌入

若是咱们但愿把静态文件编译进 Go 的二进制文件的话,在以往须要借助 go-bindata/go-bindata 这类第三方开源库来实现。app

而从 Go1.16 起,经过 go:embed 就能够快速实现这个功能:函数

import _ "embed"

//go:embed hello.txt
var s string
print(s)

经过对变量 s 声明 go:embed 指令,使其在编译时读取当前目录下的 hello.txt 文件。

最终变量 s 就会输出 hello.txt 文件中的字符串内容。

新增 io/fs 的支持

新增了标准库 io/fs,正式将文件系统相关的基础接口抽象到了该标准库中。

之前的话大可能是在 os 标准库中,这一步抽离更进一步的抽象了文件树的接口。在后续的版本中,你们能够优先考虑使用 io/fs 标准库。

调整切片扩容策略

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,保证了两种的一致。

支持 Apple Silicon M1

众所周知,最新版本的 Mac 采用了新的 64 位 ARM 架构,所以在 Go1.16 后正式支持了 GOOS=darwinGOARCH=arm64

而相应的先前用于 iOS 端口的,将改成 GOOS=iosGOARCH=arm64

同时 Apple M1 能不能很好的跑好 Go 语言程序也是各大微信群爱讨论的问题,在 GoLand 上:

图来自网络,路过微信群看见

须要注意,GoLand 的一些给你要到后续的新版本才能够使用。

调整 Go modules 策略

从 Go1.16 起,Go modules 的环境变量 GO111MODULE 默认开关将为 on,再也不是以前是 auto 了。

还在使用 GOPATH,或 Go modules 没切全的同窗这一块须要特别注意。

新增 GODEBUG inittrace

GODEBUG 新增 inittrace 指令,能够用于 init 方法的排查:

$ GODEBUG=inittrace=1 go run main.go

输出结果:

init internal/bytealg @0.008 ms, 0 ms clock, 0 bytes, 0 allocs
init runtime @0.059 ms, 0.026 ms clock, 0 bytes, 0 allocs
init math @0.19 ms, 0.001 ms clock, 0 bytes, 0 allocs
init errors @0.22 ms, 0.004 ms clock, 0 bytes, 0 allocs
init strconv @0.24 ms, 0.002 ms clock, 32 bytes, 2 allocs
init sync @0.28 ms, 0.003 ms clock, 16 bytes, 1 allocs
init unicode @0.44 ms, 0.11 ms clock, 23328 bytes, 24 allocs
...

主要做用是 init 函数跟踪的支持,以用于 init 调试和启动时间的概要分析,算是一个 GODEBUG 的补充功能点。

简化结构体标签

在 Go 语言的结构体中,咱们经常会由于各类库的诉求,须要对结构体的 tag 设置标识。

若是像是之前,量比较多就会变成:

type MyStruct struct {
  Field1 string `json:"field_1,omitempty" bson:"field_1,omitempty" xml:"field_1,omitempty" form:"field_1,omitempty" other:"value"`
}

但在 Go1.16 及之后,就能够经过合并的方式:

type MyStruct struct {
  Field1 string `json,bson,xml,form:"field_1,omitempty" other:"value"`
}

方便和简洁了很多。

总结

在本次 Go1.16 中带来了很多小优化和新的特性支持。离 Go1.18 的泛型又近了一步。

另外在本次新版本中,像是 template 支持跨行:

{{"hello" |
   printf}}

又或是 Linux 的默认内存管理策略下又从 MADV_FREE 改回了 MADV_DONTNEED 策略,你们在新版本中再也不须要设置:

GODEBUG=madvdontneed=1

你们如有需求均可以进一步去了解,如今新版本的功能特性已经锁定,基本尘埃落定。

传送门:https://tip.golang.org/doc/go...

个人公众号

分享 Go 语言、微服务架构和奇怪的系统设计,欢迎你们关注个人公众号和我进行交流和沟通。

最好的关系是互相成就,各位的点赞就是煎鱼创做的最大动力,感谢支持。

相关文章
相关标签/搜索