package main
func main() {
for _,y:=range []int{1,2,3,4,5} {
go func() {
print(y)
}()
}
print("start...")
}
结果是
start...5555
为什么不打印12345
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
这个问题实际上与Go语言的并发机制和变量捕获有关,而非阿里云产品的直接范畴。不过,我可以帮助解释这个现象。
在你的代码中,你使用了go func()
来启动goroutines(Go中的轻量级线程)来并行打印数组[]int{1,2,3,4,5}
中的每个元素。但是,由于你在for循环内部启动goroutine,并且闭包函数捕获了循环变量y
,这里发生了一个常见的闭包陷阱。
当循环运行时,所有的goroutines几乎同时开始执行,但它们都共享同一个y
变量的内存地址。在循环结束时,y
的值是5,因此所有goroutine打印的是循环结束时y
的最终值,即5,而不是它们各自迭代时的值1到4。
要解决这个问题,确保每个goroutine捕获其迭代时y
的独立副本,你可以通过在循环内部创建一个新的变量来实现这一点,如下所示:
package main
import "fmt"
func main() {
for _, y := range []int{1, 2, 3, 4, 5} {
y := y // 创建y的副本
go func() {
fmt.Print(y)
}()
}
fmt.Println("start...")
}
在这个修改后的版本中,每次迭代都会创建一个新的y
变量副本,这样每个goroutine就都能正确地打印出它应该打印的数字。不过,需要注意的是,由于goroutines的并发执行特性,"start..."的打印顺序可能仍然不固定,它可能出现在任何数字之前或之后,具体取决于goroutines的调度。