导读:Golang 开发者社区对编程语言最基本的控制流语句( for循环)最近的一些变化议论纷纷。
在最新版本的Go 语言v1.22中,现在每次的for循环都会在每次传递时迭代变量。在 Go 的所有早期版本中,定义for循环的声明变量没有改变。
这一更改解决了一个微妙但经常遇到的问题,特别是在并发程序中使用闭包时出现。“这种无意识的共享错误影响了所有 Go 程序员,无论他们是刚刚开始学习 Go 还是已经使用了十年。”现在,Go 1.22 中的代码范围将变更。如下代码:
#From the Golang spec
for i := 0; i < 5; i++ {
prints = append(prints, func() { println(i) })
i++
}
for _, p := range prints {
p()
}
以上程序将打印这些数字:
1
3
5
1
2
3
1
3
5
而不是像 Go 1.21 之前版本,只会不断重复初始变量值:
6
6
6
1
2
3
6
6
6
有网友解释道,这是“变量范围方式的根本性改变,它将循环变量更改为每次迭代范围,而不是整个循环范围。”
这将使那些需要循环更改的情况变得更容易,例如并行测试或并发编程中的闭包。
事实上,那些学习 Go 的人经常被教导如何解决这个问题,开发者常常忘记手动干预来解决这个问题,然后需要通过linter进行清理工作。
受到此错误严重影响的一项服务是Let's Encrypt证书服务,由于错误应用 Go的 for循环,该服务在 2020 年让300 万个证书失效。
Golang 中的简单整数
对于for循环的另一项更改:现在可以让范围超过整数。Carlana Johnson在有关该版本的Changelog Go Time播客中指出,此举减少了样板文件。
这里有一些语法糖,供开发者享受。到现在为止,他们一直使用相当麻烦的旧 C 风格和表达式格式来定义for循环的范围:
(i = 0; i < 5; i++)
使用 Go 1.22,可以使用如下代码...
for i := range(5)
并且就像以前一样,程序将迭代 5 次,直到达到值等于4 (0-1-2-3-4)。
这种简化虽然是一个小小的改变,但仍然可以节省敲键盘次数,特别是在基准测试软件等情况下,例如重复复制同一组指令的情况。
Go 刚刚迈入函数式编程
很快,Golang 也可能能够扩展各种功能。新版本的编程语言预览了函数范围中迭代器的变化。
我们可以在 1.22 中通过将其添加到构建中来启用此功能:
GOEXPERIMENT=rangefunc
匿名科技观察家ThePrimeagen在Twitch 评论中称赞道:
“Go!Go!Go!太棒了!”
此功能类似于其他语言中的生成器函数。简而言之,它可以将任何函数变成迭代器。
自从Go 中引入泛型以来,Go的开发人员创建了许多库。然而,Go 没有迭代这些泛型模式。
range 语句现在可以调用生成迭代器值的函数。Carlana Johnson说:
“看起来有点古怪。它会稍微改变你的想法,但是,当你编写代码时,情况并没有那么糟糕。你基本上可以只编写一个返回的小函数,你就能得到一个迭代器,”
例如,这个功能很好用,可以迭代二叉树。
Go 已经实现了大约95% 的功能,ThePrimeagen 兴奋地说:“它只需要更好的迭代器支持,而且它已经完全具备了。”
Golang 每六个月更新一次,下一个版本将于8月份正式发布~