Go 1.16将于2021年2月发布。目前已经进入freeze状态,即不再接受新feature,仅fix bug、编写文档和接受安全更新等。
目前Go 1.16的发布说明尚处于早期草稿阶段,但Go团队成员正在致力于编写发布说明。Go 1.16的完全特性列表说明还得等真正发布前才能得到。如今要了解Go 1.16功能特性都有哪些变化,只能结合现有的release note以及从Go 1.16里程碑中的issue列表中挖掘。
下面就“挖掘”到的Go 1.16重要功能特性变化做简要的且不完全的前瞻。
1. 支持Apple Silicon M1芯片
Apple Silicon M1芯片Macbook的发布让Go团队紧急为Go 1.16增加对M1的支持。如果要跨平台编译,只需设定GOOS=darwin, GOARCH=arm64即可构建出可以在搭载M1芯片的Macbook上运行的Go应用。
同时Go 1.16还增加了对ios/amd64的支持,主要是为了支持在amd64架构上的MacOS上运行ios模拟器。
2. RISC-V架构支持cgo和-buildmode=pie
RISC-V架构很可能是未来5-10年挑战ARM的最主要架构,Go语言持续加大对RISC-V架构的支持,在Go 1.16中对linux/riscv64又增加了cgo支持以及-buildmode=pie。不过目前对risc-v仍仅限于linux os。
3. 有关go module的变化
-
module-aware模式成为默认状态。如要回到gopath mode,将GO111MODULE设置为auto;
-
go build和go test不会修改go.mod和go.sum文件。能修改这两个文件的命令只有go get和go mod tidy;
-
go get之前的构建和安装go包的行为模式将被废弃。go get将专注于分析依赖,并获取go包/module,更新go.mod/go.sum;
-
go install将恢复自己构建和安装包的“角色”(在go module加入后,go install日益受到冷落,这次翻身了);
-
go.mod将支持retract指示符,包或module作者可以利用该指示符在自己module的go.mod中标记某些版本撤回(因不安全、不兼容或损坏等原因),不建议使用。
-
go.mod中的exclude指示符语义变更:Go 1.16中将忽略exclude指示的module/包依赖;而之前的版本go工具链仅仅是跳过exclude指示的版本,而使用该依赖包/module的下一个版本。
-
-i build flag废弃;
-
go get的-insecure命令行标志选项作废,可以用GOINSECURE环境变量指示go get是否通过不安全的http去获取包;
4. 支持在Go二进制文件中嵌入静态文件(文本、图片等)
Go 1.16新增go:embed指示符和embed标准库包,二者一起用于支持在在Go二进制文件中嵌入静态文件。下面是一个在Go应用中嵌入文本文件用于http应答内容的小例子:
1// hello.txt 2 3hello, go 1.16 4 5 6 7// main.go 8 9package main 10 11 12 13import ( 14 15_ "embed" 16 17"net/http" 18 19) 20 21 22 23//go:embed hello.txt 24 25var s string 26 27 28 29func main() { 30 31http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 32 33w.Write([]byte(s)) 34 35})) 36 37http.ListenAndServe(":8080", nil) 38 39} 40
上述源码中的go:embed指示符的含义是:将hello.txt内容存储在字符串变量s中。我们构建该源码,并验证一下s中存储的是否是hello.txt中的数据:
1$ go build -o demo main.go 2 3$ mv hello.txt hello.txt.bak // 将hello.txt改名,我们看看数据是否真的已经嵌入到二进制文件demo中了 4 5$ ./demo 6 7 8 9$curl localhost:8080 10 11hello, go 1.16 12
5.GODEBUG环境变量支持跟踪
当GODEBUG环境变量包含inittrace=1时,Go运行时将会报告各个源代码文件中的init函数的执行时间和内存开辟消耗情况。比如对于上面的程序demo,我们按如下命令执行:
1# GODEBUG=inittrace=1 ./demo 2 3init internal/bytealg @0.014 ms, 0 ms clock, 0 bytes, 0 allocs 4 5init runtime @0.033 ms, 0.015 ms clock, 0 bytes, 0 allocs 6 7init errors @0.24 ms, 0.003 ms clock, 0 bytes, 0 allocs 8 9init sync @0.47 ms, 0.001 ms clock, 16 bytes, 1 allocs 10 11init io @0.66 ms, 0 ms clock, 144 bytes, 9 allocs 12 13init internal/oserror @0.85 ms, 0 ms clock, 80 bytes, 5 allocs 14 15init syscall @1.0 ms, 0.006 ms clock, 624 bytes, 2 allocs 16 17init time @1.2 ms, 0.013 ms clock, 384 bytes, 8 allocs 18 19init path @1.4 ms, 0.003 ms clock, 16 bytes, 1 allocs 20 21init io/fs @1.6 ms, 0 ms clock, 16 bytes, 1 allocs 22 23init context @2.3 ms, 0.002 ms clock, 128 bytes, 4 allocs 24 25init math @2.5 ms, 0 ms clock, 0 bytes, 0 allocs 26 27init strconv @2.7 ms, 0 ms clock, 32 bytes, 2 allocs 28 29init unicode @2.9 ms, 0.065 ms clock, 23736 bytes, 26 allocs 30 31init bytes @3.2 ms, 0 ms clock, 48 bytes, 3 allocs 32 33init crypto @3.3 ms, 0.001 ms clock, 160 bytes, 1 allocs 34 35init reflect @3.5 ms, 0.002 ms clock, 0 bytes, 0 allocs 36 37init encoding/binary @3.7 ms, 0 ms clock, 16 bytes, 1 allocs 38 39init crypto/cipher @3.8 ms, 0 ms clock, 16 bytes, 1 allocs 40 41init crypto/aes @4.0 ms, 0.003 ms clock, 16 bytes, 1 allocs 42 43init internal/poll @4.1 ms, 0 ms clock, 64 bytes, 4 allocs 44 45init os @4.2 ms, 0.029 ms clock, 544 bytes, 13 allocs 46 47init fmt @4.4 ms, 0.003 ms clock, 32 bytes, 2 allocs 48 49init math/rand @4.5 ms, 0.023 ms clock, 5440 bytes, 3 allocs 50 51init math/big @4.7 ms, 0.002 ms clock, 32 bytes, 2 allocs 52 53init crypto/sha512 @4.8 ms, 0.004 ms clock, 0 bytes, 0 allocs 54 55init encoding/asn1 @5.0 ms, 0.004 ms clock, 224 bytes, 7 allocs 56 57init vendor/golang.org/x/crypto/cryptobyte @5.1 ms, 0 ms clock, 48 bytes, 2 allocs 58 59init crypto/ecdsa @5.3 ms, 0 ms clock, 48 bytes, 3 allocs 60 61init bufio @5.4 ms, 0.003 ms clock, 176 bytes, 11 allocs 62 63init crypto/rand @5.6 ms, 0.001 ms clock, 120 bytes, 4 allocs 64 65init crypto/rsa @5.7 ms, 0.007 ms clock, 648 bytes, 18 allocs 66 67init crypto/sha1 @5.8 ms, 0 ms clock, 0 bytes, 0 allocs 68 69init crypto/sha256 @5.9 ms, 0 ms clock, 0 bytes, 0 allocs 70 71init encoding/base64 @5.9 ms, 0.006 ms clock, 1408 bytes, 4 allocs 72 73init crypto/md5 @6.0 ms, 0 ms clock, 0 bytes, 0 allocs 74 75init encoding/hex @6.1 ms, 0 ms clock, 16 bytes, 1 allocs 76 77init crypto/x509/pkix @6.1 ms, 0.001 ms clock, 624 bytes, 2 allocs 78 79init path/filepath @6.2 ms, 0 ms clock, 16 bytes, 1 allocs 80 81init vendor/golang.org/x/net/dns/dnsmessage @6.3 ms, 0.009 ms clock, 1616 bytes, 27 allocs 82 83init net @6.3 ms, 0.029 ms clock, 2840 bytes, 74 allocs 84 85init crypto/dsa @6.5 ms, 0 ms clock, 16 bytes, 1 allocs 86 87init crypto/x509 @6.5 ms, 0.016 ms clock, 4768 bytes, 15 allocs 88 89init io/ioutil @6.7 ms, 0.002 ms clock, 16 bytes, 1 allocs 90 91init vendor/golang.org/x/sys/cpu @6.7 ms, 0.009 ms clock, 1280 bytes, 1 allocs 92 93init vendor/golang.org/x/crypto/chacha20poly1305 @6.8 ms, 0 ms clock, 16 bytes, 1 allocs 94 95init vendor/golang.org/x/crypto/curve25519 @6.9 ms, 0 ms clock, 0 bytes, 0 allocs 96 97init crypto/tls @7.0 ms, 0.007 ms clock, 1600 bytes, 11 allocs 98 99init log @7.0 ms, 0 ms clock, 80 bytes, 1 allocs 100 101init mime @7.1 ms, 0.008 ms clock, 1232 bytes, 4 allocs 102 103init mime/multipart @7.2 ms, 0.001 ms clock, 192 bytes, 4 allocs 104 105init compress/flate @7.3 ms, 0.012 ms clock, 4240 bytes, 7 allocs 106 107init hash/crc32 @7.4 ms, 0.014 ms clock, 1024 bytes, 1 allocs 108 109init compress/gzip @7.5 ms, 0 ms clock, 32 bytes, 2 allocs 110 111init vendor/golang.org/x/text/transform @7.5 ms, 0 ms clock, 80 bytes, 5 allocs 112 113init vendor/golang.org/x/text/unicode/bidi @7.6 ms, 0.005 ms clock, 272 bytes, 2 allocs 114 115init vendor/golang.org/x/text/secure/bidirule @7.7 ms, 0.008 ms clock, 16 bytes, 1 allocs 116 117init vendor/golang.org/x/text/unicode/norm @7.8 ms, 0.002 ms clock, 0 bytes, 0 allocs 118 119init vendor/golang.org/x/net/idna @7.8 ms, 0 ms clock, 0 bytes, 0 allocs 120 121init vendor/golang.org/x/net/http/httpguts @7.9 ms, 0.002 ms clock, 848 bytes, 3 allocs 122 123init vendor/golang.org/x/net/http2/hpack @7.9 ms, 0.063 ms clock, 22440 bytes, 32 allocs 124 125init net/http/internal @8.1 ms, 0.005 ms clock, 1808 bytes, 3 allocs 126 127init vendor/golang.org/x/net/http/httpproxy @8.2 ms, 0 ms clock, 336 bytes, 2 allocs 128 129init net/http @8.3 ms, 0.026 ms clock, 10280 bytes, 113 allocs 130
我们看到各个依赖包中的init函数执行的消耗情况都被输出了出来,根据这些信息,我们可以很容易判断出init函数中可能存在的性能问题或瓶颈。
6. 链接器进一步优化
既Go 1.15实现了go linker的第一阶段优化后,Go 1.16中继续实施了对linker的第二阶段优化。优化后的链接器要平均比Go 1.15的快20%-25%,消耗的内存却减少5%-15%。
7. struct field的tag中的多个key可以合并写
如果某个结构体支持多种编码格式的序列化和反序列化,比如:json、bson、xml,那么之前版本需要按如下书写该结构体的字段tag,冗长且重复:
1type MyStruct struct { 2 3Field1 string `json:"field_1,omitempty" bson:"field_1,omitempty" xml:"field_1,omitempty" form:"field_1,omitempty" other:"value"` 4 5} 6
Go 1.16支持将多个key进行合并,上面的tag可以写成如下形式:
1type MyStruct struct { 2 3Field1 string `json bson xml form:"field_1,omitempty" other:"value"` 4 5} 6
8. 其他改变
-
新增runtime/metrics包,以替代runtime.ReadMemStats和debug.ReadGCStats输出runtime的各种度量数据,这个包更通用稳定,性能也更好;
-
新增io/fs包,用于提供只读的操作os的文件树的高级接口;
-
对Unicode标准的支持从12.0.0升级为13.0.0。
附录:安装go tip版本的两种方式
1) 从源码安装
1$git clone https//github.com/golang/go.git 2 3$cd go/src 4 5$./all.bash 6
2) 使用gotip工具安装
1$go get golang.org/dl/gotip 2 3$gotip download 4
Go技术专栏“改善Go语⾔编程质量的50个有效实践”正在慕课网火热热销中!本专栏主要满足广大gopher关于Go语言进阶的需求,围绕如何写出地道且高质量Go代码给出50条有效实践建议,上线后收到一致好评!78元简直就是白菜价,简直就是白piao! 欢迎大家订阅
我的网课“Kubernetes实战:高可用集群搭建、配置、运维与应用”在慕课网热卖中,欢迎小伙伴们订阅学习!
Gopher Daily(Gopher每日新闻)归档仓库 -github.com/bigwhite/gopherdaily
我的联系方式:
-
微博:weibo.com/bigwhite20xx
-
博客:tonybai.com
-
github: github.com/bigwhite
点击查看更多内容