# 第 04 课:for 循环 ## 学习目标 第三课学会了根据条件选择分支,这一课学习重复执行代码。按 [main.go](./main.go) 中的 1~6 节逐段手敲,每完成一节就编译运行一次。 本课独立存放,共享根目录的 `go.mod`,只使用标准库,不需要新增依赖。 ## 1. 三段式循环 ```go for i := 1; i <= 3; i++ { fmt.Println(i) } ``` 和 C 的 `for (int i = 1; i <= 3; i++)` 类似,但 Go 不需要外面的圆括号,大括号不能省略。 执行顺序: 1. `i := 1`:初始化一次。 2. `i <= 3`:每轮执行前判断,为 false 时退出。 3. 执行大括号中的循环体。 4. `i++`:本轮结束后加一,然后回到第 2 步。 这里的 `i` 只在 for 语句内有效。Go 的 `i++` 是独立语句,不能写成 `x := i++`,也没有 `++i` 写法。 ## 2. 条件循环与无限循环 Go 没有 `while` 关键字,用 `for 条件` 表达: ```go count := 3 for count > 0 { fmt.Println(count) count-- } ``` 不写条件时就是无限循环: ```go for { // 需要用 break 等方式退出,否则会一直执行。 } ``` 如果忘记更新条件相关的变量,可能发生死循环。在终端按 `Ctrl + C` 可以中断正在运行的程序。 ## 3. break 与 continue | 语句 | 作用 | | --- | --- | | `break` | 结束当前循环,继续执行循环后面的代码 | | `continue` | 跳过本轮剩余代码,进入下一轮 | 本课只用单层循环;后续遇到嵌套时,要注意无标签的 break / continue 不会同时控制所有层。 在三段式循环中,`continue` 后仍执行更新语句。只有条件的循环则要自己保证变量得到更新,避免 `continue` 跳过更新造成死循环。 `n % 2` 表示除以 2 的余数;余数为 0 可以判断整数是偶数。`sum += n` 等价于 `sum = sum + n`。 ## 4. range 遍历字符串 ```go for index, char := range "Go语言" { fmt.Printf("字节索引:%d,字符:%c\n", index, char) } ``` - `index` 是本次 Unicode 码点在字符串中的起始字节索引,不是第几个字。 - `char` 是 `rune`(`int32` 的别名),这里用 `%c` 输出字符。 - UTF-8 下的“语”“言”各占 3 字节,因此索引是 `0、1、2、5`,不是 `0、1、2、3`。 - 如果只需要字符,不需要索引,可以写 `for _, char := range "Go语言"`,`_` 表示忽略该值。 这里先接触简单字符串遍历,不要求本课深入掌握 Unicode。下一课再学习数组与切片的遍历。 ## 编译并运行 在**仓库根目录**执行: ```powershell New-Item -ItemType Directory -Force bin/04_loops | Out-Null go build -o ./bin/04_loops/loops.exe ./lessons/04_loops .\bin\04_loops\loops.exe ``` 修改源码后需要重新编译,已有 exe 不会自动更新。 快速编译并运行: ```powershell go run ./lessons/04_loops ``` 也可以从根目录进入本课,再运行: ```powershell Set-Location lessons/04_loops go run . ``` ## 预期输出 ```text === 三段式循环 === 第 1 次学习 Go 第 2 次学习 Go 第 3 次学习 Go === 累加求和 === 1 到 5 的和:15 === 条件循环 === 倒计时:3 倒计时:2 倒计时:1 开始! === continue:只输出奇数 === 奇数:1 奇数:3 奇数:5 === break:结束循环 === 第 1 次尝试 第 2 次尝试 第 3 次尝试 循环已结束,后续代码继续执行 === range:遍历字符串 === 字节索引:0,字符:G 字节索引:1,字符:o 字节索引:2,字符:语 字节索引:5,字符:言 ``` ## 动手练习 - [ ] 把第一段改成输出 5 次,观察 `<=` 与 `<` 的区别。 - [ ] 计算 1 到 100 的和,核对结果 `5050`。 - [ ] 把倒计时改为从 5 开始。 - [ ] 修改 continue 的条件,改为只输出偶数 `2、4`。 - [ ] 把 break 的退出条件改为第 5 次,确认循环结束后的提示仍然输出。 - [ ] 用 `for _, char := range "你好Go"` 只输出字符。 如果另外手敲一份,放进本课的 `practice/` 子目录并在根目录用 `go run ./lessons/04_loops/practice` 运行,不要在同一个包中声明两个 `main` 函数。 [上一课:if 条件判断](../03_conditions/README.md) · [学习总览](../../README.md)