for-range造就循环永动机?快来看看go中for-range的那些事!

   日期:2020-09-30     浏览:93    评论:0    
核心提示:来自公众号:新世界杂货铺文章目录循环永动机神奇的指针map的随机遍历参考循环永动机Q1: 如果我们在遍历数组的同时修改数组元素,能否得到一个永远都不会停止的循环呢?func main() { arr := []int{1, 2, 3} for _, v := range arr { arr = append(arr, v) } fmt.Println(arr)}// 输出: 1 2 3 1 2 3上述代码的输出意味着循环只遍历了原始切片中的三个元素,我们遍历切片时追加的.

来自公众号:新世界杂货铺

文章目录

      • 循环永动机
      • 神奇的指针
      • map的随机遍历
      • 参考

循环永动机

Q1: 如果我们在遍历数组的同时修改数组元素,能否得到一个永远都不会停止的循环呢?

func main() { 
 arr := []int{ 1, 2, 3}
 for _, v := range arr { 
     arr = append(arr, v)
 }
 fmt.Println(arr)
}
// 输出: 1 2 3 1 2 3

上述代码的输出意味着循环只遍历了原始切片中的三个元素,我们遍历切片时追加的元素不会增加循环的执行次数, 所以循环最终还是停了下来

答: 对于所有的range循环, Go语言会在编译期间将原切片或者数组赋值给一个新的变量ha, 在赋值的过程中就发生了拷贝, 所以我们遍历的切片已经不是原始的切片变量了

神奇的指针

Q2: 我们遍历一个数组时,如果获取range返回变量的地址并保存到另一个数组或哈希时, 就会遇到令人困惑的现象

func main() { 
    arr := []int{ 1, 2, 3}
    newArr := []*int{ }
    for _, v := range arr { 
        newArr = append(newArr, &v)
    }
    for _, v := range newArr { 
        fmt.Println(*v)
    }
}
// 输出: 3 3 3

答: 遇到这种同时遍历索引和元素的range循环时, go语言会额外创建一个新的v2变量存储切片中的元素, 循环中使用的这个变量v2会在每一次迭代被重新赋值而覆盖, 在赋值时也发生了拷贝. 因为在循环中返回的变量的地址都完全相同, 所以才会出现神奇的指针的现象

map的随机遍历

Q3: go语言中使用range遍历哈希表时, 往往都会得到不同的结果?

答: 但这并不是说明哈希表不稳定, 这是go语言故意这样设计的, 他在运行时为哈希表遍历引入不确定性, 也是告诉所有使用go语言的使用者, 程序不要依赖于哈希表的稳定遍历。

参考

https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-for-range/

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服