对于 range 应用时有个点须要留神一下,防止踩坑
平时应用 range 时都是这样
for i, element := range xxxx
有没有思考过 element 是如何赋值的?每次循环 element 是否是新生成长期变量?
先看看如下代码的运行后果
idNum := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
waitGrp := sync.WaitGroup{}
for index, unit := range idNum {waitGrp.Add(1)
fmt.Printf("unit(%d) addr:%p value:%d \n", index, &unit, unit)
/*
go func(num int) {fmt.Printf("------Num:%d, unit addr:%p \n", num, &num)
waitGrp.Done()}(unit)
*/
go func() {fmt.Printf("******Num:%d, unit addr:%p \n", unit, &unit)
waitGrp.Done()}()}
waitGrp.Wait()
输入后果如下
unit(0) addr:0xc0000ae040 value:0
unit(1) addr:0xc0000ae040 value:1
unit(2) addr:0xc0000ae040 value:2
unit(3) addr:0xc0000ae040 value:3
unit(4) addr:0xc0000ae040 value:4
unit(5) addr:0xc0000ae040 value:5
unit(6) addr:0xc0000ae040 value:6
unit(7) addr:0xc0000ae040 value:7
unit(8) addr:0xc0000ae040 value:8
unit(9) addr:0xc0000ae040 value:9
unit(10) addr:0xc0000ae040 value:10
unit(11) addr:0xc0000ae040 value:11
unit(12) addr:0xc0000ae040 value:12
unit(13) addr:0xc0000ae040 value:13
unit(14) addr:0xc0000ae040 value:14
unit(15) addr:0xc0000ae040 value:15
******Num:14, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:3, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:15, unit addr:0xc0000ae040
******Num:10, unit addr:0xc0000ae040
看第一局部输入
unit(0) addr:0xc0000ae040 value:0
unit(1) addr:0xc0000ae040 value:1
unit(2) addr:0xc0000ae040 value:2
unit(3) addr:0xc0000ae040 value:3
unit(4) addr:0xc0000ae040 value:4
unit(5) addr:0xc0000ae040 value:5
unit(6) addr:0xc0000ae040 value:6
unit(7) addr:0xc0000ae040 value:7
unit(8) addr:0xc0000ae040 value:8
unit(9) addr:0xc0000ae040 value:9
unit(10) addr:0xc0000ae040 value:10
unit(11) addr:0xc0000ae040 value:11
unit(12) addr:0xc0000ae040 value:12
unit(13) addr:0xc0000ae040 value:13
unit(14) addr:0xc0000ae040 value:14
unit(15) addr:0xc0000ae040 value:15
就能够明确了,element 的地址是不变的,每次都是对同一个变量赋值的
所以在 routine 中间接拜访 element 时失去的是刹时以后的值。
如果想要在 routine 中应用每次循环的 element 值,将 element 值传入就能够了
go func(num int) {fmt.Printf("------Num:%d, unit addr:%p \n", num, &num)
waitGrp.Done()}(unit)