golang两种在for循环中使用goroutine的错误形式
程序员文章站
2022-03-25 19:11:24
1. 闭包中使用循环体中变化的量 platground链接: "https://play.golang.org/p/6x6_tuQNjUO" golang type Value struct{ val int } func (v Value)print(){ time.Sleep(time.Seco ......
1. 闭包中使用循环体中变化的量
platground链接:
https://play.golang.org/p/6x6_tuqnjuo
type value struct{ val int } func (v *value)print(){ time.sleep(time.second) fmt.println(v.val) } func main() { vals := make([]value,0) for i := 0; i <10;i++ { vals = append(vals, value{val:i,}) } for _,v := range vals{ // 这种形式,闭包方式共享了主协程的变量v // 而变量v是不断变化的,所以导致print的值都是最后一个 go func(){ v.print() }() } time.sleep(time.second*3) }
运行结果: 9 9 9 9 9 9 9 9 9 9
2. receiver为指针时候,创建goroutine
playground链接:
https://play.golang.org/p/6quzin6zwsm
type value struct{ val int } func (v *value)print(){ time.sleep(time.second) fmt.println(v.val) } func main() { vals := make([]value,0) for i := 0; i <5;i++ { vals = append(vals, value{val:i,}) } for _,v := range vals{ // print方法的receiver是(*value)类型,而此处v是一个value类型 // 所以每次print传值都传递了&v。 // 在for loop中,v的值变化,但是&v不会改变 // 在其他goroutine中执行时,print的内容不可预期,取决于当时的v值 go v.print() } time.sleep(time.second*3) }
运行结果: 4 4 4 4 4