目录

Go 控制流

控制流决定了代码的执行顺序。Go 提供了 ifforswitch 等控制流语句,语法简洁而强大。值得一提的是,Go 只有 for 循环,没有 whiledo-while。本篇将详细讲解 Go 中各种控制流语句的用法。

https://img.zhaojq.top/20260729161337213.png
控制流程

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。但它可以实现其他语言中 whilefor、无限循环的功能。

经典 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 用于跳出最近的 forswitchselect 语句:

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 支持使用标签来配合 breakcontinue 跳出多层嵌套循环:

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 会使代码流程难以追踪,绝大多数情况下可以用 forbreakcontinue 替代。仅在错误处理等少数场景中可能有用。

综合示例

下面是一个综合运用控制流的小程序:

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 穿透;breakcontinue 配合标签可以精确控制嵌套循环的跳转。Go 的控制流设计简洁而实用,去除了许多传统语言中的冗余语法。