
示例工程教程【免费下载链接】learngo❤️ 1000 Hand-Crafted Go Examples, Exercises, and Quizzes. Learn Go by fixing 1000 tiny programs.项目地址https://gitcode.com/gh_mirrors/le/learngo点击查看免费下载导读在 Go 语言中循环只有一种形态——for语句但它通过灵活的组合可以表达 while、无限循环、遍历等几乎所有循环场景。本文以 learngo 仓库中 13-loops/questions/01-loops.md 的十道核心题目为骨架结合 13-loops 目录下的可运行示例源码系统讲解for的三要素语法、条件省略、break/continue的跳转语义以及for range对切片和命令行参数的遍历技巧。读完本文你将能准确预测任意for循环的打印结果并能在实战中写出正确、简洁的循环代码。一、Go 中唯一的循环语句forGo 语言刻意保持语法精简循环语句只有一种for。没有while、forever、until这类关键字。当需要当型循环或无限循环时都是通过省略for的相应子句来实现的。// 经典三要素形式init; condition; post for i : 1; i 1000; i { sum i }这一点可以在仓库的 13-loops/01-basics/main.go 中得到印证——用一段循环把 1 累加到 1000替代了原来逐行手写的sum 1、sum 2等语句。二、三要素形式init、condition、post 的执行顺序for的完整写法是for init; condition; post { // 循环体 }执行流程为先执行一次init循环变量初始化然后判断condition为真则执行循环体再执行post通常是自增/自减接着回到条件判断如此往复。题目for i : 3; i 0; i--打印什么for i : 3; i 0; i-- { fmt.Println(i) }正确答案是3 2 1。初始i 3条件i 0成立打印 3执行i--后为 2打印 2再减为 1打印 1再减为 0 时条件不成立循环结束。注意这里与 C 系语言的do...while不同Go 的for是先判断、后执行所以i 0时循环体根本不会执行。三、省略 post 子句把递增逻辑移入循环体post子句是可以省略的。此时循环的推进逻辑需要由程序员自己在循环体内完成否则容易写出死循环。题目for i : 3; i 0; { i--; ... }打印什么for i : 3; i 0; { i-- fmt.Println(i) }正确答案是2 1 0。关键在于i--被放进了循环体且发生在fmt.Println(i)之前第一次迭代时i先自减为 2 再打印最后一次迭代时i从 1 自减为 0 再打印随后条件i 0不成立循环结束。这道题与上一题形成鲜明对比post子句中的i--在打印之后执行循环体内的i--在打印之前执行顺序不同输出完全不同。这是 Go 初学者最容易踩的坑之一。四、无限循环与 break手动控制退出当for的三个子句全部省略时就得到了无限循环for { // 永远循环直到遇到 break 或 return }仓库 13-loops/02-break/main.go 正是这种写法配合break在满足条件时退出var ( sum int i 1 ) for { if i 5 { break } sum i fmt.Println(i, --, sum) i }break会立即终止最内层的for、switch或select语句把控制权交给其后的第一条语句。题目for i : 3; ; { if i 0 { break }; ... }打印什么for i : 3; ; { if i 0 { break } i-- fmt.Println(i) }正确答案是2 1 0。这里省略了condition和post只保留init循环本身无限执行靠循环体内的break终止迭代序列为i3→ 自减为 2 打印 → 自减为 1 打印 → 自减为 0 打印 → 下一次判断i 0成立break退出。简化题for ; true; {}可以怎么简化for ; true ; { // ... }正确答案是直接写成for { // ... }因为condition恒为true时与省略该子句等价。这也是 Go 社区中无限循环的标准写法。其他候选答案如for true、for true;、for ; true都不是合法的简化形式——Go 语法要求for后要么跟init; condition; post要么只跟一个条件表达式或range子句不能只跟一个裸布尔值再加大括号。五、continue跳过本次迭代进入下一次continue与break相反它不终止循环而是跳过当前迭代的剩余部分直接进入下一次循环执行post或重新判断条件。题目for i : 2; i 9; i配合continue打印什么for i : 2; i 9; i { if i % 3 ! 0 { continue } fmt.Println(i) }正确答案是3 6 9。i从 2 递增到 9每当i % 3 ! 0时执行continue跳过打印因此只有能被 3 整除的 3、6、9 被输出。仓库 13-loops/03-continue/01-b-after/main.go 展示了continue的一个真实陷阱在无限循环中跳过迭代前必须先推进循环变量否则continue会不断跳过i导致死循环for { if i 10 { break } if i%2 ! 0 { // 关键先 i 再 continue否则死循环 i continue } sum i fmt.Println(i, --, sum) i }经验法则在continue之前务必确保循环变量已经被推进。六、for range遍历切片与命令行参数for range是 Go 遍历集合的最常用方式可以对切片、数组、字符串、map 和 channel 进行迭代。对切片而言它每次迭代返回两个值索引index和元素的拷贝value。for i, v : range os.Args[1:] { fmt.Println(i1, v) }题目 Afor i, v : range os.Args[1:]打印什么假设程序这样运行go run main.go go is awesome则os.Args[1:]是[go, is, awesome]正确答案是1 go 2 is 3 awesome这里把os.Args切片后取第 1 个元素到末尾跳过程序名range返回的索引从 0 开始所以用i1把编号显示为 1、2、3。题目 B只用索引for i : range os.Args[1:]打印什么for i : range os.Args[1:] { fmt.Println(i1) }正确答案是1 2 3注意当只需要索引、不需要值时range子句可以只写一个接收变量。题目 C只用值for _, v : range os.Args[1:]打印什么for _, v : range os.Args[1:] { fmt.Println(v) }正确答案是go is awesome这里用空白标识符_丢弃索引只打印元素值。_是 Go 中处理不需要的返回值的标准手段——如果声明了i却不使用编译器会报错。题目 Dfor range os.Args计数打印什么var i int for range os.Args { i } fmt.Println(i)正确答案是4。os.Args包含程序名本身共 4 个元素main.go、go、is、awesome。这道题揭示了for range的一个重要用途用range来计数——当循环体不关心索引也不关心值时可以连接收变量都省略。仓库 13-loops/05-for-range/01-loop-over-slices/main.go 完整展示了三种遍历命令行参数的思路并明确标注第三种for _, v : range os.Args[1:]直接切片跳过程序名是最佳方式// #1st way: 传统 for从索引 1 开始 // for i : 1; i len(os.Args); i { ... } // #2nd way: range 全量遍历用 continue 跳过索引 0 // for i, v : range os.Args { // if i 0 { continue } // ... // } // #3rd way (best): 切片 range只取需要的值 for _, v : range os.Args[1:] { fmt.Printf(%q\n, v) }七、仓库实战印证嵌套循环与标签跳转理解for的三种子句省略方式和range的取值规则之后就可以阅读仓库中更复杂的循环应用。嵌套循环九九乘法表13-loops/04-nested-loops-multiplication-table/main.go 用双重for打印乘法表外层循环负责行内层循环负责列for i : 0; i max; i { // 打印行头 fmt.Printf(%5d, i) // 打印单元格 for j : 0; j max; j { fmt.Printf(%5d, i*j) } fmt.Println() }嵌套循环中裸break只能跳出内层循环要跳出外层循环就需要用到标签。带标签的 break跳出外层循环13-loops/08-word-finder-labeled-break/main.go 在双层循环中给外层循环贴上标签queries内层命中第一个匹配单词后用break queries直接跳出两层循环queries: for _, q : range query { for i, w : range words { if q w { fmt.Printf(#%-2d: %q\n, i1, w) // 找到第一个匹配就退出整个双层循环 break queries } } }这里的关键点也是 13-loops/questions/03-labeled-statements.md 中的知识点标签的作用域是整个函数体而不是它所在的语句块——这也是goto能在函数内任意跳转的原因一个标签同一时刻只能标注一条语句continue只能配合循环标签使用如果标签标注的是switch等非循环语句编译会报错无标签的break只终止最近的一层语句可能是switch不会连带终止外层for。另外goto同样能实现循环内跳转但语义更难跟踪实际编码中应优先使用带标签的break/continue。八、小结与自测知识点速查表语法形态等价含义典型场景for init; condition; post {}完整三要素循环固定次数迭代for condition {}相当于while条件驱动循环for {}无限循环配合break/return退出for i, v : range slice {}同时取索引与值遍历集合for i : range slice {}只取索引需要下标时for _, v : range slice {}只取值仅处理元素for range slice {}只计数统计元素个数break终止最近一层语句提前退出循环/switchcontinue跳过本次迭代过滤不需要的元素break label/continue label跳转到指定标签退出/跳过嵌套多层十个判断要点Go 只有for一种循环语句for i : 3; i 0; i--打印3 2 1——post在循环体之后执行把i--移入循环体后打印2 1 0——执行顺序决定结果for i : 3; ; {}是无限循环靠循环体内break退出同样输出2 1 0for i : 2; i 9; i配合if i%3 ! 0 { continue }只打印3 6 9for ; true; {}应简化为for {}for i, v : range os.Args[1:]对go run main.go go is awesome输出1 go / 2 is / 3 awesomefor i : range os.Args[1:]只输出索引1 2 3for _, v : range os.Args[1:]只输出值go / is / awesomefor range os.Args可用于计数程序名 3 个参数共计数 4 次。建议实战路径先运行 13-loops/01-basics/main.go、13-loops/02-break/main.go 等基础示例验证输出再尝试 13-loops/exercises 中的练习如01-sum-the-numbers、04-only-evens、05-break-up最后对照 13-loops/05-for-range/01-loop-over-slices/main.go 和 13-loops/08-word-finder-labeled-break/main.go 掌握实战中的遍历与标签跳转技巧。只有亲手运行并预测输出才能真正内化for的执行顺序与break/continue的跳转语义。赞分享示例工程教程【免费下载链接】learngo❤️ 1000 Hand-Crafted Go Examples, Exercises, and Quizzes. Learn Go by fixing 1000 tiny programs.项目地址https://gitcode.com/gh_mirrors/le/learngo点击查看免费下载相关推荐iloader Nightly构建指南为什么以及如何尝鲜最新版侧载功能iloader Nightly构建指南为什么以及如何尝鲜最新版侧载功能 iloader 是一款用户友好的 iOS 侧载工具sideloader支持一键安文档教程前端uni-app x UTS 语言循环语法全解析for、for...of、for...in、while 与 break/continue 的多端一致性实践uni app x UTS 语言循环语法全解析for、for...of、for...in、while 与 break/continue 的多端一致性实践 导读示例工程前端移动开发跨平台Claude Desktop Debian版备份与恢复用户配置迁移指南Claude Desktop Debian版备份与恢复用户配置迁移指南 Claude Desktop Debian版是Linux用户运行Claude AI桌面开发工具桌面应用上一篇Claude Security 插件的 CWE 第三方数据声明CWE-1003 视图、MITRE 许可条款与代码落地解析下一篇QuestDB 修复 PR 评审意见fix-pr 技能完整实践指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考