for range 注意的点(坑)                  
        
          
          
            |
            
              
              字数总计:
              1076
              |
              
              阅读时长:
              1分钟
              |
              
                阅读量:
                191
              
          
         
       
              
        这篇文章距离最后更新已过358          天,如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!
        
       
      
        
      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的遍历过程与数组基本一致。