for range 注意的点(坑)
|
字数总计:
1076
|
阅读时长:
1分钟
|
阅读量:
367
这篇文章距离最后更新已过45 天,如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!
package main
import "fmt"
func main() {
a := [3]int{0, 1, 2}
fmt.Printf("遍历前第一个元素内存地址:%p\n", &a[0])
fmt.Printf("遍历前第二个元素内存地址:%p\n", &a[1])
fmt.Printf("遍历前第三个元素内存地址:%p\n", &a[2])
for i, v := range a {
fmt.Printf("遍历中元素内存地址:%p\n", &v)
if i == 0 {
a[1], a[2] = 999, 999 //直接对底层进行修改
fmt.Println(a) //修改成功
}
a[i] = v + 100 //v是复制品,值分别是0,1,2
}
fmt.Println(a)
}
遍历前第一个元素内存地址:0xc00001a1f8
遍历前第二个元素内存地址:0xc00001a200
遍历前第三个元素内存地址:0xc00001a208
遍历中元素内存地址:0xc00001e0d8
[0 999 999]
遍历中元素内存地址:0xc00001e0d8
遍历中元素内存地址:0xc00001e0d8
[100 101 102]
总结需要注意的点:
1、在遍历时,获取的值地址相比遍历前已发生变化,且在遍历时获取的值的地址唯一。
2、在遍历时,有且只有一个变量副本。
3、通过下标访问能直接修改数组中的元素。
range for array底层实现:
1、遍历前获取数组的长度作为循环次数,在循环体中,每次循环会先获取元素值,如果for-range中接收index和value的话,会对index和value进行一次赋值,所以要尽量避免对大元素进行遍历而影响性能,因为大量赋值会产生gc。
2、在遍历开始前循环次数就已经确定了,所以循环过程中新添加的元素是不可能遍历到的。
3、数组指针和slice的遍历过程与数组基本一致。