流程控制

if / else

Go 的 if 无需括号,且可以在条件前执行一条初始化语句,变量作用域限定在该分支内:

package main

import (
    "errors"
    "fmt"
)

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("除数不能为零")
    }
    return a / b, nil
}

func main() {
    // 初始化语句 + 条件判断,err 仅在 if 作用域内可见
    if v, err := divide(10, 3); err != nil {
        fmt.Println("错误:", err)
    } else {
        fmt.Printf("结果: %.2f\n", v)
    }
}
Tip

if err := f(); err != nil 是 Go 错误处理的标志性写法。将初始化语句放入 if 中可以收窄变量作用域,减少命名污染。

for:唯一的循环关键字

Go 只有 for 一种循环,通过形式变化覆盖所有场景:

package main

import "fmt"

func main() {
    // 1. 经典三段式
    for i := 0; i < 5; i++ {
        fmt.Print(i, " ")
    }
    fmt.Println()

    // 2. 仅条件(等价于其他语言的 while)
    sum := 1
    for sum < 100 {
        sum *= 2
    }
    fmt.Println("sum =", sum)

    // 3. 无限循环,配合 break 退出
    count := 0
    for {
        count++
        if count >= 3 {
            break
        }
    }
    fmt.Println("count =", count)

    // 4. range 遍历切片与映射
    langs := []string{"Go", "Python", "Rust"}
    for idx, val := range langs {
        fmt.Println(idx, val)
    }
}

range 遍历中,若不需要下标可使用空标识符 _ 忽略:

for _, val := range langs {
    fmt.Println(val)
}

switch

Go 的 switch 默认每个分支自动 break,不需要显式书写;case 可以是多个值或非常量表达式:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 基本用法:多值匹配
    switch day := time.Saturday; day {
    case time.Saturday, time.Sunday:
        fmt.Println("周末")
    default:
        fmt.Println("工作日")
    }

    // 无表达式 switch:替代 if/else 链
    score := 85
    switch {
    case score >= 90:
        fmt.Println("优秀")
    case score >= 80:
        fmt.Println("良好")
    case score >= 60:
        fmt.Println("及格")
    default:
        fmt.Println("不及格")
    }

    // fallthrough:强制继续执行下一个分支(慎用)
    switch n := 2; n {
    case 1:
        fmt.Println("one")
    case 2:
        fmt.Println("two")
        fallthrough
    case 3:
        fmt.Println("three") // 会被执行
    }
}
Tip

Go 1.22 起,for range 循环变量在每次迭代中都是新变量,直接在闭包中引用循环变量是安全的;早期版本(≤1.21)则存在变量共享问题。

break / continue 与标签

嵌套循环中,可通过标签跳出外层循环:

package main

import "fmt"

func main() {
outer:
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            if i == 1 && j == 1 {
                break outer // 直接跳出两层循环
            }
            fmt.Println(i, j)
        }
    }
}

goto 在 Go 中存在但极少使用,可读性更好的替代方案是提取函数或使用标签 break/continue

select:并发中的流程控制

selectswitch 在通道(channel)上的专用形式,用于多路复用等待,详见并发编程章节。

小结

  • if 支持初始化语句,是错误处理的标准载体。
  • for 是唯一循环关键字,配合 range 遍历集合。
  • switch 自动 break,无表达式形式可替代 if/else 链。