Go 控制流
控制流决定了代码的执行顺序。Go 提供了 if、for、switch 等控制流语句,语法简洁而强大。值得一提的是,Go 只有 for 循环,没有 while 和 do-while。本篇将详细讲解 Go 中各种控制流语句的用法。
if 语句
if-else 与多分支
package main
import "fmt"
func main() {
age := 16
if age >= 18 {
fmt.Println("成年人")
} else {
fmt.Println("未成年人")
}
score := 85
if score >= 90 {
fmt.Println("优秀")
} else if score >= 80 {
fmt.Println("良好")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
}if 带初始化语句
Go 的 if 支持在条件前加一个初始化语句,变量的作用域限定在 if 代码块内:
package main
import (
"fmt"
"math/rand"
)
func main() {
// 初始化语句中声明的变量仅在 if 块内可见
if n := rand.Intn(100); n%2 == 0 {
fmt.Printf("%d 是偶数\n", n)
} else {
fmt.Printf("%d 是奇数\n", n)
}
// fmt.Println(n) // 编译错误:n 未定义
}for 语句
Go 只有一种循环结构:for。但它可以实现其他语言中 while、for、无限循环的功能。
经典 for 循环(三要素)
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Printf("第 %d 次循环\n", i+1)
}
}条件 for(相当于 while)
省略初始化和后置语句,只保留条件:
package main
import "fmt"
func main() {
n := 1
for n < 100 { // 相当于 while n < 100
n *= 2
}
fmt.Println("结果:", n) // 128
}无限 for
省略所有三个部分,形成无限循环:
package main
import "fmt"
func main() {
count := 0
for {
count++
if count >= 5 {
break
}
fmt.Println("循环中...", count)
}
fmt.Println("循环结束")
}range 关键字
range 是 Go 中用于遍历数据结构的关键字,可以用于数组、切片、字符串、map 和 channel。
遍历数组/切片
package main
import "fmt"
func main() {
fruits := []string{"苹果", "香蕉", "橙子", "葡萄"}
// 获取索引和值
for i, fruit := range fruits {
fmt.Printf("[%d] %s\n", i, fruit)
}
// 只获取值(忽略索引)
for _, fruit := range fruits {
fmt.Println(fruit)
}
// 只获取索引
for i := range fruits {
fmt.Println("索引:", i)
}
}switch 语句
Go 的 switch 比 C 语言更灵活,不需要写 break(自动终止),且条件不限于整数。
基本 switch
package main
import "fmt"
func main() {
day := "Monday"
switch day {
case "Monday":
fmt.Println("星期一")
case "Tuesday":
fmt.Println("星期二")
case "Wednesday":
fmt.Println("星期三")
case "Thursday":
fmt.Println("星期四")
case "Friday":
fmt.Println("星期五")
default:
fmt.Println("周末")
}
}一个 case 匹配多个值
package main
import "fmt"
func main() {
month := 3
switch month {
case 3, 4, 5:
fmt.Println("春天")
case 6, 7, 8:
fmt.Println("夏天")
case 9, 10, 11:
fmt.Println("秋天")
case 12, 1, 2:
fmt.Println("冬天")
default:
fmt.Println("无效月份")
}
}无条件 switch(相当于多个 if-else)
package main
import "fmt"
func main() {
score := 85
switch {
case score >= 90:
fmt.Println("优秀")
case score >= 80:
fmt.Println("良好")
case score >= 60:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
}fallthrough
Go 的 switch 默认不穿透(自动 break),如果需要穿透到下一个 case,必须显式使用 fallthrough:
package main
import "fmt"
func main() {
n := 2
switch n {
case 1:
fmt.Println("是一")
case 2:
fmt.Println("是二")
fallthrough // 继续执行下一个 case
case 3:
fmt.Println("也会执行这里(fallthrough)")
case 4:
fmt.Println("不会执行这里")
}
}注意:
fallthrough只能放在 case 的最后一行,且不会判断下一个 case 的条件。
break 和 continue
break
break 用于跳出最近的 for、switch 或 select 语句:
package main
import "fmt"
func main() {
// 找到第一个能被 7 整除的数就停止
for i := 1; i <= 100; i++ {
if i%7 == 0 {
fmt.Println("找到:", i)
break
}
}
}continue
continue 跳过当前循环的剩余部分,进入下一次迭代:
package main
import "fmt"
func main() {
// 只打印奇数
for i := 1; i <= 10; i++ {
if i%2 == 0 {
continue // 跳过偶数
}
fmt.Print(i, " ")
}
fmt.Println()
// 输出: 1 3 5 7 9
}标签(Label)
Go 支持使用标签来配合 break 和 continue 跳出多层嵌套循环:
package main
import "fmt"
func main() {
// 使用标签跳出嵌套循环
outer:
for i := 0; i < 5; i++ {
for j := 0; j < 5; j++ {
if i*j > 6 {
fmt.Printf("找到 i=%d, j=%d, 乘积=%d\n", i, j, i*j)
break outer // 跳出外层循环
}
}
}
}goto 语句
Go 保留了 goto 语句,但一般不推荐使用。它可以在同一函数内跳转到指定标签:
package main
import "fmt"
func main() {
// 简单演示 goto(实际开发中不推荐)
count := 0
loop:
count++
if count < 5 {
fmt.Println("count =", count)
goto loop
}
fmt.Println("循环结束, count =", count)
}建议:
goto会使代码流程难以追踪,绝大多数情况下可以用for、break、continue替代。仅在错误处理等少数场景中可能有用。
综合示例
下面是一个综合运用控制流的小程序:
package main
import (
"fmt"
"math/rand"
)
func main() {
target := rand.Intn(100) + 1
fmt.Println("我想了一个 1-100 之间的数字,猜猜看!")
for attempt := 1; attempt <= 7; attempt++ {
var guess int
fmt.Printf("第 %d 次猜测: ", attempt)
fmt.Scanf("%d", &guess)
switch {
case guess < target:
fmt.Println("太小了!")
case guess > target:
fmt.Println("太大了!")
default:
fmt.Printf("恭喜你!答案就是 %d\n", target)
return
}
}
fmt.Printf("游戏结束!答案是 %d\n", target)
}总结
本篇详细介绍了 Go 的控制流语句。if 语句支持带初始化语句的独特语法;for 是 Go 唯一的循环关键字,通过不同写法可以实现经典循环、条件循环和无限循环;range 提供了优雅的遍历方式;switch 无需 break 且支持多值匹配和 fallthrough 穿透;break 和 continue 配合标签可以精确控制嵌套循环的跳转。Go 的控制流设计简洁而实用,去除了许多传统语言中的冗余语法。