19|控制结构:Go的for循环,仅此一种
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
Go语言中for循环的多种形式及其灵活应用是本文的主要内容。文章首先介绍了经典for循环形式,详细解释了循环前置语句、条件判断表达式、循环体和循环后置语句的执行顺序和作用。其次,讲解了使用多循环变量的复杂例子,并指出循环前置和后置语句都是可选的。此外,介绍了for循环的另外两种形式:仅保留循环判断条件表达式和无限循环形式。最后,详细介绍了for range形式的应用,以及带label的continue语句和break语句的使用方法,以及它们在嵌套循环中的应用。文章还提到了与for语句相关的常见“坑”点,主要集中在for range这个“语法糖”上。通过对这些内容的解释,读者能够全面了解并掌握Go语言中for循环的使用方法,同时也提醒读者在使用for range时需要注意避免常见的“坑”点。文章内容涵盖了for循环的各种形式和应用场景,为读者提供了全面的学习和使用指南。
《Tony Bai · Go 语言第一课》,新⼈⾸单¥59
全部留言(34)
- 最新
- 精选
- 布凡老师,最后问题三:遍历 map 中元素的随机性中举的例子没看懂: 1、示例1中,当 k="tony"作为第一个迭代的元素时,我们将得到如下结果:包含了“tony”,是因为for循环中读取的是“tony”不允许被删除吗? 2、示例2中,是当m["lucky"]=24 这个值被其它原map中的值覆盖,导致赋值不成功吗? 还请老师指教
作者回复: 1. 不是啊。之所以还能输出tony,是因为k, v从map中获取值的操作发生在delete之前啊。如果k="tony"作为第一个迭代的元素时,我们用k,v从map中取出了tony, 21。然后delete掉tony,此时k, v的值已经是tony, 21了,输出就正常了。如果tony不是第一个迭代元素,那么已经被删除掉了,后续迭代就不会输出它了。 2. 不是被覆盖了。对map迭代的实质是按顺序逐个bucket的遍历,每个bucket也是逐个遍历其中的key。如果luckey创建与第一个被遍历的元素之前了,那么后续就不会遍历它了。别忘了,key存储在哪里是根据hash值来定的。
2021-11-2442 - 用0和1改变自己用数组指针替换数组 func main() { var a = [5]int{1, 2, 3, 4, 5} var r [5]int fmt.Println("original a =", a) for i, v := range &a { //a 改为&a if i == 0 { a[1] = 12 a[2] = 13 } r[i] = v } fmt.Println("after for range loop, r =", r) fmt.Println("after for range loop, a =", a) }
作者回复: 正确✅
2021-11-24337 - lesserrorTony Bai老师,你在评论中说:“如果luckey创建与第一个被遍历的元素之前了,那么后续就不会遍历它了。别忘了,key存储在哪里是根据hash值来定的”。 这个我还是似懂非懂,能举例说明一下么? 非常感谢。
作者回复: map的遍历顺序有随机性。但这种随机仅仅是在创建初始iterator时随机选择一个bucket。假设按bucket2->bucket3->...顺序迭代,假设已经遍历完bucket2,正在遍历bucket3,此时插入lucy这个key,恰插到bucket2中,由于之前已经遍历完bucket2,后续的遍历不会再重复遍历bucket2,于是lucy便无法出现在后续遍历路径上。如果lucy插入到bucket3后面的bucket中,则会出现在遍历路径上,我们就能看到这个key。
2021-12-01516 - 罗杰map 中的坑比想象的要多,使用的时候一定要细心。老师基本上把能遇到的坑都指出来了。惭愧的是 continue 和 break 的 label 从来没用过。
作者回复: 看来你日常写的业务逻辑还不够复杂。居然没有嵌套循环:)
2021-11-2438 - crabxyj问题三:java 中是不允许在遍历中修改当前集合的,和fastfail有关,直接会抛出异常,而go允许,但遍历结果不可控
作者回复: 👍
2022-02-1627 - 奕对于 map 遍历的那个例子,新增一个 map key m["lucy"] = 24 , 这里的结果counter 不应该一直是 4吗? 给 map 添加的元素为什么有的时候可以访问到 有的时候访问不到?
作者回复: 是否访问到,视m["lucy"]=24这个键值对的插入位置而定。
2021-11-2544 - 酥宝话不多传数组地址,&a
作者回复: ✅
2021-11-243 - 白小白老师,请教一下:最后一个例子的结果出现的原因正是因为map 中元素的随机性,如何能保证只输出一种结果?
作者回复: 有随机性,无法保证输出哪种结果。
2022-08-08归属地:辽宁2 - William Ning老师同学好, 关于评论列表中第一条 中的 第二个问题,就是map新元素的插入,位置是随机的,不定的,所以,可能插入到原来第一个元素的前面,也可能在后面,如果在前面,就被跳过了,便没有输出。 从个人代码执行,输出结果便可知,m["lucy"] = 24 插入的位置,确实会出现在任意的位置,因为输出的位置,从0-3都有~ 但是关于上面的回答中的“,别忘了,key存储在哪里是根据hash值来定的” 如果是这样,m["lucy"] = 24,lucy应该是一个确定的值,不论经过次重复的hash,hash值应该都是一样的,也就是说,插入的位置,应该都是确定的,那么输出结果应该只有上面结果的中的一种可能,我的理解出了什么偏差吗? 谢谢老师,同学~ 下面是输出结果,供参考 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 counter is 3 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tom 22 jim 23 lucy 24 tony 21 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tom 22 jim 23 lucy 24 tony 21 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tony 21 tom 22 jim 23 lucy 24 counter is 4 ➜ golearning go run . tom 22 jim 23 lucy 24 tony 21 counter is 4 ➜ golearning go run . jim 23 lucy 24 tony 21 tom 22 counter is 4 ➜ golearning go run . tom 22 jim 23 lucy 24 tony 21 counter is 4 ➜ golearning go run . jim 23 lucy 24 tony 21 tom 22 counter is 4
作者回复: 虽然插入的位置可能是固定的,但遍历的起点是随机的。看看你的程序输出的的结果 是不是按tony , tom , jim, lucy组成了一个环。
2022-03-1722 - pyhhou关于思考题,除了换成切片或者指针外,我们可以将 for range 替换为传统的 for ;; 循环就可以解决问题。 这里有一个衍生的问题,还烦请老师解答,如果说 for range 会对遍历的结构产生副本,那么我们用 for range 去遍历大型的数组的话是不是会有性能或者资源浪费等问题?所以说在平时,我们还是尽量用传统的三段式 for 循环而不是 for range?这样即使是不太了解 go 的人来看代码也不会有困惑
作者回复: 好问题!我是这么想的: 第一尽量用切片代替纯数组loop吧,这样可以获得稳定且一致的性能。 第二,即便纯数组loop,for range也不一定比经典for loop性能差,go语言对for range做了特殊优化。不过也要看for range的数组的元素类型,如果是包含一定数量字段的结构体类型,目前优化还不到位。
2022-03-102