Golang语法系列——闭包函数
本文最后更新于:5 年前
常见坑
for语句的闭包中迭代变量使用不妥
data := []string{"one","two","three"}
wg := sync.WaitGroup{}
wg.Add(9)
//goroutines print: three, three, three
for _,v := range data {
go func() {
fmt.Println(v)
wg.Done()
}()
}
//goroutines print: one, two, three
for _,v := range data {
vcopy := v // 使用临时变量
go func() {
fmt.Println(vcopy)
wg.Done()
}()
}
//goroutines print: one, two, three
for _,v := range data {
go func(in string) {
fmt.Println(in)
wg.Done()
}(v)
}
wg.Wait()
在for迭代过程中,迭代变量v会一直保留,只是每次迭代值v不一样,因此在for循环中在闭包里直接引用迭代变量,在执行时直接取迭代变量的值,而不是闭包所在迭代的变量值
闭包要取所在迭代变量的值,需要for中定义临时变量来保存所在迭代的值,或者通过闭包函数传参
定义为指针数组时,输出正常
另一个例子:
data := []field{{"one"},{"two"},{"three"}}
for _,v := range data {
// 解决办法:添加如下语句
// v := v
go v.print()
}
time.Sleep(3 * time.Second) //goroutines print: three, three, three
data2 := []*StructA{{"one"}, {"two"}, {"three"}} // 注意data2是指针数组 StructA 自定义结构
for _, v := range data2 {
go v.print() // go执行是函数,函数执行之前,函数的接受对象已经传过来
}
time.Sleep(3 * time.Second) //goroutines print: one, two, three
本站点所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!