前言
Go官方团队在2022.06.11发布了Go 1.19 Beta 1版本,Go 1.19的正式release版本预计会在今年8月份发布。
让我们先睹为快,看看Go 1.19给我们带来了哪些变化。
这是Go 1.19版本更新内容详解的第1篇,欢迎大家关注公众号,及时获取本系列最新更新。
Go 1.19发布清单
和Go 1.18相比,改动相对较小,主要涉及语言(Language)、内存模型(Memory Model)、可移植性(Ports)、Go Tool工具链、运行时(Runtime)、编译器(Compiler)、汇编器(Assembler)、链接器(Linker)和核心库(Core library)等方面的优化。
我们逐个看看具体都有哪些变化。
语言变化
语言层面的变化很小,只有一个和泛型相关的优化,调整了泛型函数和方法声明里的类型参数(type parameter)的作用域,不影响现有代码。
为什么会有这个调整呢?我们来看看如下的代码
type T[T any] struct {
m1 T
}
这段代码定义了泛型类型T
,类型参数列表(type parameter list)里的类型参数(type parameter)命名也是T
,代码可以正常编译通过。
但是如下代码呢?
type T[T any] struct {
m1 T
}
func(t T[T]) print() {
fmt.Println(t.m1)
}
我们定义了泛型类型T
的方法print
,编译上面的代码,编译器会提示:
./main.go:11:8: T is not a generic type
也就是说编译器认为方法print
里的第一个T
不是泛型类型,为什么会这样呢?我们来看看官方说明[1]:
The scope of an identifier denoting a type parameter of a function or declared by a method receiver is the function body and all parameter lists of the function.
这段说明对应到上面的代码,编译器会认为print
方法里的第2个T
(类型参数T
)的作用域是函数体以及函数的参数列表(这里的参数列表包括方法receiver parameter list和函数名后面的参数列表)。因此第2个T
就覆盖了第1个T
,所以编译器会提示T is not a generic type
。
这个问题[2]是由Go101作者提出来的,Go泛型的设计者Robert Griesemer[3]认领了这个问题,把类型参数的作用域按照如下说明进行调整:
The scope of an identifier denoting a type parameter of a function or declared by a method receiver starts after the function name and ends at the end of the function body.
也就是类型参数的作用域是从函数名后面开始一直到函数体,这样上面的代码里的2个T
的就不会覆盖第1个T
,编译器也就不会编译报错了。
想了解Go泛型的使用方法、设计思路和最佳实践,推荐大家阅读:
内存模型
Go内存模型[4] 在Go 1.19版本做了修改,和C, C++, Java, JavaScript, Rust和Swift对齐。Go只提供顺序一致原子操作(sequentially consistent atomics),不提供其它语言里更宽松的内存模型,比如因果一致性(casual consistency)、最终一致性(eventual consistency)。
伴随着内存模型的修改,Go 1.19版本在sync/atomic
包里引入了新的类型,例如atomic.Int64[5]和atomic.Pointer[T][6],这些新的类型可以让开发者使用原子操作时更容易。
想了解Go原子操作和使用方法,推荐大家阅读:
可移植性
Go 1.19版本支持Linux操作系统上的中国龙芯64位CPU架构。
GOOS=linux
GOARCH=loong64
此外,Go现在支持在riscv64
架构上使用寄存器来传递函数参数和函数执行结果。性能测试表明,riscv64
架构上的Go语言性能提升了大概10%。
总结
下一篇会介绍Go 1.19在Go Tool工具链、运行时、编译器、汇编器、链接器和核心库的优化工作,有一些内容值得学习,欢迎大家保持关注。
福利
我为大家整理了一份后端开发学习资料礼包,包含编程语言入门到进阶知识(Go、C++、Python)、后端开发技术栈、面试题等。
关注公众号「coding进阶」,发送消息 backend 领取资料礼包,这份资料会不定期更新,加入我觉得有价值的资料。还可以发送消息「进群」,和同行一起交流学习,答疑解惑。
开源地址
文章和示例代码开源在GitHub: Go语言初级、中级和高级教程[7]。
公众号:coding进阶。关注公众号可以获取最新Go面试题和技术栈。
个人网站:Jincheng's Blog[8]。
知乎:无忌[9]。
References
-
https://tip.golang.org/doc/go1.19 -
https://int64.me/2020/%E4%B8%80%E8%87%B4%E6%80%A7%E6%A8%A1%E5%9E%8B%E7%AC%94%E8%AE%B0.html
参考资料
官方说明: https://go.dev/ref/spec#Declarations_and_scope
[2]这个问题: https://github.com/golang/go/issues/52038
[3]Robert Griesemer: https://github.com/griesemer
[4]Go内存模型: https://tip.golang.org/ref/mem
[5]atomic.Int64: https://pkg.go.dev/sync/atomic@master#Int64
[6]atomic.Pointer[T]: https://pkg.go.dev/sync/atomic@master#Pointer
[7]Go语言初级、中级和高级教程: https://github.com/jincheng9/go-tutorial
[8]Jincheng's Blog: https://jincheng9.github.io/
[9]无忌: https://www.zhihu.com/people/thucuhkwuji
文章评论