关于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)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。