工具
module相关
- go build等命令默认将会使用 -mod=vendor,如果需要使用mod cache需要显示指定 -mod=mod。
- go mod init 设置go.mod文件是-mod=readonly,go.mod是只读模式的。
- go mod tidy之外的go命令不再编辑go.mod文件
- 除非明确要求或已经要求该版本,否则 go get 将不再升级到该模块的不兼容主要版本。直接从版本控制中获取时,go list 还会忽略此模块的不兼容版本
- 在 module 模式下,go 命令支持 SVN 仓库
- go test -v 现在将 t.Log 输出流式传输,而不是在所有测试数据结束时输出
编译和运行时
goroutine 支持异步抢占
在Go1.1版本中,调度器还不支持抢占式调度,只能依靠 goroutine 主动让出 CPU 资源,存在非常严重的调度问题。
Go1.12中编译器在特定时机插入函数,通过函数调用作为入口触发抢占,实现了协作式的抢占式调度。但是这种需要函数调用主动配合的调度方式存在一些边缘情况,就比如说下面的例子:
func main() {
runtime.GOMAXPROCS(1)
go func() {
for {
}
}()
time.Sleep(time.Millisecond)
println("OK")
}
上面代码中,其中创建一个goroutine并挂起, main goroutine 优先调用了 休眠,此时唯一的 P 会转去执行 for 循环所创建的 goroutine,进而 main goroutine 永远不会再被调度。换一句话说在Go1.14之前,上边的代码永远不会输出OK,因为这种协作式的抢占式调度是不会使一个没有主动放弃执行权、且不参与任何函数调用的goroutine被抢占。
Go1.14 实现了基于信号的真抢占式调度解决了上述问题。Go1.14 程序启动时, 会在函数runtime.sighandler 中注册了 SIGURG 信号的处理函数 runtime.doSigPreempt,在触发垃圾回收的栈扫描时,调用函数挂起goroutine,并向M发送信号,M收到信号后,会让当前goroutine陷入休眠继续执行其他的goroutine。
defer性能大幅提升
time.Timer 定时器性能得到大幅提升
语法
允许嵌入具有重叠方法集的接口
如下的接口定义在 Go1.14 之前是不允许的:
type ReadWriteCloser interface {
io.ReadCloser
io.WriteCloser
}
因为 io.ReadCloser 和 io.WriteCloser 中 Close 方法重复了,编译时会提示:duplicate method Close。在Go1.14中支持了这种重复接口集
testing 包新增CleanUp 方法
testing包的T、B和TB都加上了CleanUp方法,它将以后进先出的方式执行 f(如果注册多个的话)。
如下代码,输出结果是 test cleanup, clear resourcce:
func TestCleanup(t *testing.T) {
t.Cleanup(func() {
t.Log("clear resource")
})
t.Log("test cleanup")
}
cleanup还能在defer之后执行
添加了新包 hash/maphash
这个新包提供了字节序列上的 hash 函数。这些哈希函数用于实现哈希表或其他的数据结构,这些哈希表或其他数据结构需要将任意字符串或字节序列映射为整数的均匀分布。这些 hash 函数具有抗冲突性,但不是加密安全的。
库
代码包 | 改动 |
---|---|
reflect | reflect 在 StructField 元素中设置了 PkgPath 字段,StructOf 支持使用未导出字段创建结构类型。 |
crypto/tls | 移除了对 SSLv3 的支持;默认开启 TLS1.3,通过 Config.MaxVersion 字段配置其版本而不是通过 DEBUG 环境变量进行配置 |
strconv | NumError 类型新增加了一个 UnWrap 方法,可以用于找到转换失败的原因,可以用 Errors.Is 来查看 NumError 值是否是底层错误:strconv.ErrRange 或 strconv.ErrSyntax |
runtime | runtime.Goexit 不再被递归的 panic/recover 终止 |
runtime/pprof | 生成的 profile 不再包括用于内联标记的伪 PC。内联函数的符号信息以 pprof 工具期望的格式编码 |
net/http | 新的 Header 方法的 Values 可用于获取规范化 Key 关联的所有值,新的 Transport 字段 DialTLSContext 可用于指定可选的以非代理 https 请求创建 TLS 连接的 dail 功能 |
mime/multipart | 新的 Reader 方法 NextRawPart 支持获取下一个 MIME 的部分,而不需要透明的解码引用的可打印数据 |
signal | Windows 上,CTRL_CLOSE_EVENT、CTRL_LOGOFF_EVENT、CTRL_SHUTDOWN_EVENT 将生成一个 syscall.SIGTERM 信号,类似于 Control-C 和 Control-Break 如何生成 syscall.SIGINT 信号 |
math | 新的 FMA 函数在浮点计算 xy + z 的时候,不对 xy 计算进行舍入处理(几种体系结构使用专用的硬件指令来实现此计算,以提高性能) |
math/bits | 新的函数 Rem,Rem32,Rem64 即使在商溢出时也支持计算余数 |
go/build | Context 类型有了一个新字段 Dir,用于设置 build 的工作目录 |
unicode | 整个系统中的 unicode 包和相关支持已经从 Unicode1.0 升级到了 Unicode12.0,增加了 554 个新字符,其中包括 4 个脚本和 61 个新 emoji |
生态建设
https://pkg.go.dev 是 go.org的配套网站,里边有精选用例和其他资源的信息,提供了godoc.org 之类的 Go 文档,但它使用起来更方便,并提供了有关软件包先前版本的信息,它还可以检测并显示许可证,并具有更好的搜索算法。