Go1.13将正式开始Go2开发历程

2,082 阅读4分钟
原文链接: mp.weixin.qq.com


了解Go语言2.0的发展方向,请关注“光谷码农”公众号。

根据Go语言的发布流程,每年的二月和八月会发布一个版本。在2019年2月已经发布了Go1.12版本,Go1.13即将在8月发布。在正式发布之前,Go1.13的相关变更日志可以从tip页面查看:https://tip.golang.org/doc/go1.13

模块化将彻底转正

模块特性从Go1.11实验性引入,经过Go1.12的社区验证,如果不出意外将在Go1.13正式启用。关于Go语言模块的特性已经有诸多文章讨论,大家可以查看相关文档。以后将和GOPATH环境变量彻底拜拜了。

安装Tip版本的Go语言

因为Go1.13还没有发布任何beta或alpha等测试版本,我们还无法从官网下载页面下载安装。不过可以通过go get命令安装tip版本:

$ go get golang.org/dl/gotip$ gotipgotip: not downloaded. Run 'gotip download' to install to /Users/chai/sdk/gotip$ gotip downloadCloning into '/Users/chai/sdk/gotip'...remote: Counting objects: 9463, doneremote: Finding sources: 100% (9463/9463)Receiving objects:   8% (758/9463), 131.97 KiB | 252.00 KiReceiving objects:  50% (4818/9463), 13.81 MiB | 116.00 KiReceiving objects: 100% (9463/9463), 22.00 MiB | 130.00 KiReceiving objects: 100% (9463/9463), 22.10 MiB | 111.00 KiB/s, done.Resolving deltas: 100% (1012/1012), done.HEAD is now at eb2fabf... text/template: clarify the safety of Template.NewBuilding Go cmd/dist using /usr/local/go.Building Go toolchain1 using /usr/local/go.Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.Building Go toolchain2 using go_bootstrap and Go toolchain1.Building Go toolchain3 using go_bootstrap and Go toolchain2.Building packages and commands for darwin/amd64.---Installed Go for darwin/amd64 in /Users/chai/sdk/gotipInstalled commands in /Users/chai/sdk/gotip/binSuccess. You may now run 'gotip'!$ gotip versiongo version devel +eb2fabf Fri Jun 7 13:56:20 2019 +0000 darwin/amd64$

首先是执行go get golang.org/dl/gotip安装tip的辅助命令,然后通过执行 gotip download下载真正的tip版本工具。下载完成之后,就可以通过totip命令来编译和运行Go程序了。

支持二进制和八进制面值常量

构建测试代码如下(hello.go):

func main() {    fmt.Println(0b00001111) // 二进制面值常量    fmt.Println(0o644)      // 八进制面值常量}

通过gotip运行程序:

$ gotip run hello.go 15420

二进制常量以0b开头,八进制以 0o开头,它们可以简化bit标志位的设置。

浮点数支持十六进制格式的面值常量

Go语言的浮点数是IEEE754标准的浮点数,本质上是二进制的规范化的科学记数法(参考:Go之父说:不懂浮点数不配当码农 mp.weixin.qq.com/s/rO5EWj5eS…)。

Go1.13将支持直接以二进制科学记数法方式的浮点数面值常量:

func main() {    fmt.Println(0x1p0)    fmt.Println(0x1p1)    fmt.Println(0x1p-1)    fmt.Println(0x1p+1)}

分别表示2的0次方、2的1次方、2的-1次方、2的+1次方。输出结果如下:

$ gotip run hello.go120.52

这样我们就可以方便指定浮点数可以精确表达的值,不容易再闹出0.3这种浮点数的笑话。

整数支持下划线数字分隔符

当数字比较长的是时候,我们一般会以三个一组或四个字组进行分隔书写,这样便于阅读。Go1.13的整数支持下划线数字分隔符。

比如下面的代码:

func main() {    fmt.Println(123_456_789)}

表示打印123456789这个整数:

$ gotip run hello.go 123456789

errors包已经开始着手实现Go2的部分工作

可以通过命令行查看errors包多了哪些函数:

$ gotip doc errorspackage errors // import "errors"Package errors implements functions to manipulate errors.func As(err error, target interface{}) boolfunc Is(err, target error) boolfunc New(text string) errorfunc Unwrap(err error) error

增加了As、Is和Unwrap三个函数。其中As用于将err错误转为具体类型的错误,Is判断错误链条中是否有某个具体错误值,而Unwrap则是调用错误对象的Unwrap方法进行错误解包。

比如以下的错误保证代码:

package mainimport (    "errors"    "fmt"    "io")type wrapped struct {    msg string    err error}func (e wrapped) Error() string { return e.msg }func (e wrapped) Unwrap() error { return e.err }func main() {    var err error = wrapped{        msg: "错误: io.EOF",        err: io.EOF,    }    fmt.Println(errors.Is(err, io.EOF)) // true    fmt.Println(err == io.EOF)          // false}

包装之后,err将无法和io.EOF直接进行相等比较。但是 errors.Is可以通过Unwrap方法逐次解包原始的错误,再依次和目标值进行比较,从而可以识别出这是io.EOF包装而来的错误。

errors.Aserrors.Is工作模式类似:遍历错误包装链条,然后对每层进行类型断言,尝试转为具体类型的错误,这样可以避免错误二次包装导致的丢失元素错误类型的问题。

Playground支持多文件和导入第三方包

https://play.golang.org/

虽然不是Go1.13的特性,但是Playground 导入第三方包是基于模块化特性,通过https://proxy.golang.org/ 模块的代理服务实现。

补充

此外还有其它一些改进。比如位移运行将支持int类型,TLS1.3将默认启用。Go命令开始并发加载依赖包,提升编译速度。JSON的解码速度提升了15%~20%,regexp包也通过更多的inline优化性能。标准库中还有诸多改进,大家可以自行查看文档。