Go 1.16新功能特性不完全前瞻

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

点击查看更多内容

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

M1 Mac使用原生Go与开发环境

Go1.16版将正式支持AppleSilicon M1芯片,即arm64架构的Mac操作系统,目前go1.16版版本为beta1,只是会在这个基础上再修修bug,改进文档等。目前有两种方式抢先体验Go1.16:方式一:编译源代码mac上需要确保安装有rosetta2(https://support.apple.com/

Go 1.16新功能特性不完全前瞻 - HelloWorld