go 1.13新特性前瞻

最新Go版本1.13在Go v1.12发布六个月后推出,它的大部分变化在于工具链、运行时和库的实现,该版本保存与Go 1的兼容性承诺。从Go 1.13开始,go命令默认使用Go module mirror和Go checksum database来下载和认证modules。本文将介绍Go1.13的变化及新特

语言的变化

根据数字文字提案,Go1.13支持更统一和现代化的数字文字前缀

Binary integer literals 前缀0b或0B表示二进制整数字面值,例如:0b1011
Octal integer literals 前缀0o或0O表示八进制整数字面值,例如:0o660。由前导0后跟八进制数字指示的现有八进制表示法仍然有效
Hexadecimal floating point literals 前缀0x或0X可以用来表示十六进制浮点数的尾数,例如:0x1.0p-1021。十六进制的浮点数必须带有指数,用p或P表示后面跟上十进制的指数,指数通过2的指数幂缩放尾数
Imaginary literals 虚数后缀i可以与任何(二进制、十进制、十六进制)整数或浮点字面值一起使用
Digit separators 可以使用下划线分隔(分组)任何数字,例如:1_000_000、0b_1010_0110、3.1415_9265,下划线可能出现在任何两位数字或字符前缀和第一位数字之间
Go 1.13之前为满足左移位(<<)和右移位(>>)运算符的操作数必须是无符号数的限制,需要进行大量手动uint类型转换。根据有符号移位计数提议,Go 1.13移除了移位操作数必须是无符号数的限制,消除手动类型转换的需要

语言层面的改变通过修改编译器以及 go/scanner、text/scanner (number literals)、go/types (signed shift counts)库来实现

如果代码使用modules和go.mod文件指定语言版本,要使用语法新特性需确保将其版本至少设置为1.13。可以直接编辑go.mod文件或使用命令`go mod edit -go=1.13`

工具链

Modules
环境变量
GO111MODULE 依然以auto为默认值,但是只要当前目录包含或者其子目录包含go.mod文件--即使当前目录在GOPATH/src中,都会激活go命令的module-aware模式。这项更改简化来GOPATH/src中现有代码的迁移并且继续维护module-aware和non-module-aware模式
GOPRIVATE 这个新的环境变量指示非公开的module路径,它用在较低级别的GONOPROXY和GONOSUMDB变量的默认值,通过代理提取哪些模块并使用校验和数据库进行验证,从而提供更细粒度的控制
GOPROXY environment variable 可以设置为以逗号分隔的代理URL列表或特殊token direct,默认值https://proxy.golang.org,direct。当解析包含其模块的包路径时,go命令将在列表中的每一个代理上陆续尝试所有候选模块路径。代理不可达或HTTP状态码不是400或410,将终止搜索而无需咨询其余代理
GOSUMDB 标识数据库名称以及可选的公钥和服务器URL,以查询主模块的go.sum文件中尚未列出的模块和校验和。如果GOSUMDB不包括显示的URL,通过探测GOPROXY URLs选择支持校验和数据库的endpoint作为URL,如果任何代理都不支持则返回到指定数据库的直接连接。如果GOSUMDB设置为off,则不会查询校验和数据库只验证go.sum文件中的现有校验和
无法访问默认代理和校验和数据库的用户(防火墙)可能会通过将GOPROXY设置为直接和/或将GOSUMDB设置为关闭来禁用

go env -w 可以设置用户的环境变量,与平台无关。默认的设置存储在go/env os.UserConfigDir()文件内
go env -w GOPROXY=direct
go env -w GOSUMDB=off
go env -u  # (unset)取消设置

go get
在module-aware模式下,go get搭配-u参数现在只更新一个更小的模块集合,这与GOPATH模式下使用go get -u命令更新软件包集更加一致
go get -u <package name>继续更新命令行上命名的模块和包,但额外只更新命名包导入的包的模块; go get 子命令现在支持版本后缀@patch,@patch后缀表示指定的模块或包含命名包的模块应更新为具有与构建列表中找到的版本相同的主要和次要版本的最高修补程序版本
特别注意,go get -u(不带参数)现在只更新当前目录中包的传递导入。要更新主模块传递的所有包(包括测试依赖项),请使用go get -u all。不再支持go get -m(go在加载包之前停止)子命令; go get -d(下载构建命名包的依赖关系所需的源代码之后停止)子命令仍然受支持
go get -u只更新非测试依赖,与GOPATH模式一致;它现在同样接受-t标识,导致go get包含由命令行上命令的包测试包导入
Version validation
从版本控制系统中提取模块时,go命令现在对请求的版本字符串执行附加验证--go命令验证伪版本和版本控制元素之间的映射
版本前缀必须vX.0.0的形式,或者从修订版本的祖先上的标记派生,或者从包含指定修订本身的构建元数据标记派生
日前字符串必须与修订的UTC时间戳匹配
修订版的短名称必须使用与go命令生成的字符数相同的字符数(对于git使用的SHA-1哈希对应一个12位数的前缀)
如果主模块中的require指令使用无效的伪版本,通常可以通过将版本编辑为提交hash并重新运行go命令来纠正,例如:go list -m all 或 go mod tidy

example
require github.com/docker/docker v1.14.0-0.20190319215453-e7b5f7dbe98c
(redacted to) => require github.com/docker/docker e7b5f7dbe98c
(currently resolves to) =>require github.com/docker/docker v0.7.3-0.20190319215453-e7b5f7dbe98c

Compiler Toolchain
编译器有一个新的更精确的逃逸分析实现。对大多数代码应该是一个改进(更多的Go变量和表达式分配在栈而不是堆);但是这种提高的精度也可能会破坏之前运行的代码使之变得无效(例如,违反unsafe.Pointer安全规则的代码)

Assembler
汇编器现在支持许多ARM v8.1中引入的许多原子指令

运行时

Out of range panic 消息现在包含出界的索引和切片的容量/长度,例如:切片s[3]长度为1,Panic消息表示runtime error: index out of range [3] with length 1
此版本将大多数使用defer的性能提高了30%
运行时更积极地将内存还给操作系统,以使其可供共同租户应用程序使用

核心库

TLS 1.3
Go 1.13的crypto/tls包默认支持TLS(可以将tls13=0添加到GODEBUG环境变量来禁用)
crypto/ed25519 实现Ed25519签名,这个功能之前由 golang.org/x/crypto/ed25519 包提供,与go 1.13+一起使用时它成为 crypto/ed25519 的包装器

Error wrapping
错误e可以通过提供返回w的Unwrap方法来包装另一个错误w。e和w都可用于程序,允许e为w提供额外的上下文或重新解释它,同时仍然允许程序基于w做出决策。更多细节清阅读errors package documentation或Error Value FAQ

更新的库

库的微小更改和更新,会考虑与Go 1的兼容性

bytes 新的ToValidUTF8函数返回给定字节切片的副本,每次运行的无效UTF-8字节序列由给定切片替换
context 通过WithValue返回的上下文格式不再依赖于fmt,也会以相同的方式进行字符换化。依赖于之前确切的字符串化的代码可能会受到影响
crypto/tls 现在已弃用对SSL 3.0版(SSLv3)的支持,将在go 1.14中删除,默认情况下禁用。TLS 1.2和1.3现在支持Ed25519证书
crypto/x509 根据RFC 8410以及ParsePKCS8PrivateKey, MarshalPKCS8PrivateKey, and ParsePKIXPublicKey函数,证书和证书请求现在支持Ed25519密钥。搜索系统根目录的路径现在包括 /etc/ssl/cert.pem
database/sql 新增 NullTime 表示time.Time为null; 新增NullInt32表示int32类型null
debug/dwarf 如果在graph类型中遇到未知DWARF标记Data.Type方法不再panic,相反,它表示具有UnsupportedType类型的对象
errors 新增三个函数

**As** 函数查找给定错误链(包装错误序列)中与给定目标类型匹配的第一个错误,如果找到则将目标设置为error value
**Is** 该函数报告给定的错误值是否与另一个链中的错误匹配
**Unwrap** 返回在给定错误(如果存在)上调用Unwrap的结果

fmt

%O以基数8格式化整数,省略0o前缀
scanner现在可接收十六进制浮点数值、下划线分隔数字、ob和0o前缀
Errorf函数有一个新的动词%w,其操作数必须是一个错误。从Errorf返回的错误将有一个Unwrap方法,它返回%w的操作数

go/scanner scanner 已经被更新到能识别新的Go数字文字,特别是具有0b/0B前缀的二进制文字、具有0o/0O前缀的八进制文字和具有十六进制尾数的浮点数,虚数后缀i可以与任何数字文字一起使用、下划线可以用作数字分隔符进行分组
go/types type-checker已经被更新为遵循整数移位新规则
html/template 使用<script>标记并将"module"设置为type属性时,代码将被解释为JavaScript模式脚本
log 新的Writer函数返回标准logger的输出目标

math/big

对于Float.Parse和Int.SetString如果基数是0,为方便阅读可以在数字之间使用下划线
Rat.SetString接受非十进制浮点表示
math/bits Add、Sub、Mul、RotateLeft和ReverseBytes 执行时间保证独立于输入

net 在Unix系统上use-vc被设置在resolv.conf,TCP用于DNS解析
新的字段ListenConfig.KeepAlive指定侦听器接受的网络连接保持活动的时段。默认值为0,启用TCP keep-alive,设置为负值可以禁用此功能
net/http

新字段Transport.WriteBufferSize 和 Transport.ReadBufferSize 允许指定传输读/写缓冲区的大小。如果任意字段为0,则使用默认大小4KB
新字段 Transport.ForceAttemptHTTP2 当提供了非零Dial、DialTLS或DialContext函数或TLSClientConfig,它控制是否启用HTTP/2
Transport.MaxConnsPerHost 在HTTP/2可以正常使用
TimeoutHandler's ResponseWriter 现在实现Pusher和Flusher接口
新增103状态码,表示Early Hints
Transport 现在使用 Request.Body's io.ReaderFrom 实现(如果可用) 来优化写入正文

os、os/exec、reflect、runtime、strconv、strings、sync、syscall、syscall/js、testing、text/scanner、text/template、time、unicode
这些包也有些许更新,这里不一一列出

小结

本文抛砖引玉式地对Go1.13的新特性做了简单介绍,更多特性需要在实际应用中去深入挖掘

推 荐 阅 读

[1] https://golang.org/doc/go1.13

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 备注:本猿翻译水平有限,请各位看客见谅 翻译内容: go1.11 版本中 go help modules文档内容 ...
    星云数联阅读 2,504评论 0 1
  • 传统Go构建以及包依赖管理 Go在构建设计方面深受Google内部开发实践的影响,比如go get的设计就深受 G...
    一根很帅的藤藤菜阅读 13,428评论 0 7
  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 3,813评论 0 5
  • 因为儿子学校组织的主题活动——“在关爱下成长”,因缘巧合,我有幸经历平生第一次孵小鸡。 蛋宝宝在孵蛋器的培...
    文字拐杖阅读 723评论 0 2
  • 你问风为什么托着候鸟飞翔 却又吹的让他慌张 你问雨为什么滋养万物生长 却也湿透他的衣裳 你问他为什么亲吻他的伤疤 ...
    wuli清修阅读 486评论 0 0