golang闭包陷阱本质原理其实是range陷阱:Golang for range陷阱
ep 1
func main() {
var values = []int{1, 2, 3, 4, 5}
for _, value := range values {
go func() {
fmt.Print(value, " ")
}()
}
time.Sleep(time.Second)
}
输出:
5 5 5 5 5
在ep 1中,values其实是一个固定变量,每次循环绑定数组元素的值,所以每次闭包都绑定的是一个变量,由于可能循环结束后闭包还没开始执行,而此时value值为5。
ep2
func main() {
var values = []int{1, 2, 3, 4, 5}
for _, value := range values {
go func(value int) {
fmt.Print(value, " ")
}(value)
}
time.Sleep(time.Second)
}
输出结果
3 4 5 1 2
因为ep2中每次传给闭包的都是一个value的拷贝,故协程被执行的时候,每个值都是可用的
ep3
func main() {
var values = []int{1, 2, 3, 4, 5}
for _, value := range values {
value := value
go func() {
fmt.Print(value, " ")
}()
}
time.Sleep(time.Second)
}
输出结果
2 1 4 3 5
方法如同Golang for range陷阱, 变量value重新定义在循环内部,这些value之间不共享,可以单独被每个闭包使用