Go 1.22对语言语法做了两处变更,一个是Go 1.21中的试验特性loopvar在Go 1.22中转正使用;另一个是for range新增了对整型表达式的支持。前者修补了代码语义的““坑”,后者是破坏性不兼容特性(旧gosdk无法编译使用该特性的代码)。
一、不再共享循环变量
for-range得到的value不再是同一个对象,在该代码块中再使用go程时,不再会出现&value的坑。
如下代码:
func main() {
values := []int{1, 2, 3, 4, 5}
for _, value := range values {
go func() {
fmt.Printf("%p, %d\n", &value, value)
}()
}
select{}
}
在不同gosdk版本下的运行结果如下:
- go1.21
0xc00000a0d8,4
0xc00000a0d8,5
0xc00000a0d8,5
0xc00000a0d8,3
0xc00000a0d8,5
- go1.22
0xc00000a0f0,2
0xc00000a108,5
0xc00000a100,4
0xc00000a0d8,1
0xc00000a0f8,3
二、支持循环整数类型
支持以下代码:
func main() {
for i := range 5 {
fmt.Println("Hello World", i)
}
}
输出结果如下:
Hello World! 0
Hello World! 1
Hello World! 2
Hello World! 3
Hello World! 4
三、总结
- 从易用性方面看,不再共享循环变量减少了并发bug的出现,支持循环整数类型简化了部分fori代码。
- 从golang语言设计层面来看,不再共享循环变量让程序员减少了心智负担,但给循环整数加了一种语法糖,某种程度上不符合go的设计理念。
延展阅读:
为什么PHP在近年来逐渐失去了领先地位,而GoLang却迅速崛起?
中小团队怎么基于PG快速迭代创新?PostgreSQL is all you need!
Mongo性能优化实战:如何通过WiredTiger引擎提升MongoDB的性能和数据安全性
Nodejs 的事件循环机制是如何处理 timers、poll 和 check 队列的?
MongoDB 4.0至7.0:这些主版本更新带来了哪些关键特性与性能飞跃?
咨询方案 获取更多方案详情