-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Go 低版本存在的循环问题 #26
Labels
Golang
fa-brands fa-golang
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
起因
在使用 ginkgo 编写测试用例时,出现了循环只检测最后一个 test case 的情况,起初这让人十分疑惑,这并不符合认知,但确实是出现了这样的问题。
解决问题
查阅 ginkgo 的文档发现 dynamically-generating-specs 中有提到循环中出现的问题,主要是把循环变量的副本赋值给局部变量,否则无法在闭包中捕获变化的循环变量
由此可以想到两种方案方案解决这个循环问题
for _, c := range cases { + c := c Context(c.name, func() { It("should return the expected results for "+c.name, func() { /// checking }) })
for _, c := range cases { + c := c Context(c.name, func() { It("should return the expected results for "+c.name, func() { /// checking }) })
后续
网上冲浪的时候,无意间看到 Go 官方 Blog 中有一篇 Fixing For Loops in Go 1.22 的文章,这不就是我在修复 test 中遇到问题嘛,点进去好好研读一番
循环问题起初出认为是 goroutine 并发导致的混淆问题
随着时间推移还出现在不使用 goroutine 的情况下
人们才开始注意到这个问题不符合常人的认知
能力小测验:下面两个代码片段哪一个是正确修复,哪一个又是无效修复?
for _, informer := range c.informerMap { + informer := informer go informer.Run(stopCh) }
for _, a := range alarms { + a := a go a.Monitor(b) }
官方修复
Golang 1.22 及其之后的版本使用全新的语义,Golang 1.21 还可以通过
GOEXPERIMENT=loopvar
在测试或者构建中使用新循环语义GOEXPERIMENT=loopvar go test
Golang 版本低于 1.21 的版本将无法得到新语义的支持
参考
Go Blog Fixing For Loops in Go 1.22
Proposal: Less Error-Prone Loop Variable Scoping
Go Wiki: LoopvarExperiment
The text was updated successfully, but these errors were encountered: