了解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
$ gotip
gotip: not downloaded. Run 'gotip download' to install to /Users/chai/sdk/gotip
$ gotip download
Cloning into '/Users/chai/sdk/gotip'...
remote: Counting objects: 9463, done
remote: Finding sources: 100% (9463/9463)
Receiving objects: 8% (758/9463), 131.97 KiB | 252.00 Ki
Receiving objects: 50% (4818/9463), 13.81 MiB | 116.00 Ki
Receiving 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.New
Building 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/gotip
Installed commands in /Users/chai/sdk/gotip/bin
Success. You may now run 'gotip'!
$ gotip version
go 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
15
420
二进制常量以0b
开头,八进制以0o
开头,它们可以简化bit标志位的设置。
浮点数支持十六进制格式的面值常量
Go语言的浮点数是IEEE754标准的浮点数,本质上是二进制的规范化的科学记数法(参考:Go之父说:不懂浮点数不配当码农 https://mp.weixin.qq.com/s/rO5EWj5eSkgWu5-0KhshHw)。
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.go
1
2
0.5
2
这样我们就可以方便指定浮点数可以精确表达的值,不容易再闹出0.3这种浮点数的笑话。
整数支持下划线数字分隔符
当数字比较长的是时候,我们一般会以三个一组或四个字组进行分隔书写,这样便于阅读。Go1.13的整数支持下划线数字分隔符。
比如下面的代码:
func main() {
fmt.Println(123_456_789)
}
表示打印123456789这个整数:
$ gotip run hello.go
123456789
errors包已经开始着手实现Go2的部分工作
可以通过命令行查看errors包多了哪些函数:
$ gotip doc errors
package errors // import "errors"
Package errors implements functions to manipulate errors.
func As(err error, target interface{}) bool
func Is(err, target error) bool
func New(text string) error
func Unwrap(err error) error
增加了As、Is和Unwrap三个函数。其中As用于将err错误转为具体类型的错误,Is判断错误链条中是否有某个具体错误值,而Unwrap则是调用错误对象的Unwrap方法进行错误解包。
比如以下的错误保证代码:
package main
import (
"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.As
和errors.Is
工作模式类似:遍历错误包装链条,然后对每层进行类型断言,尝试转为具体类型的错误,这样可以避免错误二次包装导致的丢失元素错误类型的问题。
Playground支持多文件和导入第三方包
https://play.golang.org/
虽然不是Go1.13的特性,但是Playground 导入第三方包是基于模块化特性,通过https://proxy.golang.org/ 模块的代理服务实现。
补充
此外还有其它一些改进。比如位移运行将支持int类型,TLS1.3将默认启用。Go命令开始并发加载依赖包,提升编译速度。JSON的解码速度提升了15%~20%,regexp包也通过更多的inline优化性能。标准库中还有诸多改进,大家可以自行查看文档。