首页 / Go 语言入门教程 / switch 语句

Go 语言入门教程

switch 语句

本教程共 80 篇 · 第 18 篇 · 更新于 2026-07-27 · 约 7 分钟阅读

GoGo 入门教程switchfallthrough流程控制Go switch

18. switch 语句

本节目标:掌握 Go switch 的各种用法,理解它和 C/Java switch 的关键区别,学会 fallthrough 的正确使用。

switch 基本语法

switch 是多分支选择语句,比一长串 if-else if 更清晰:

day := "Monday"

switch day {
case "Saturday", "Sunday":
    fmt.Println("周末")
case "Monday":
    fmt.Println("星期一")
case "Tuesday":
    fmt.Println("星期二")
default:
    fmt.Println("其他")
}

Go switch 的独特之处

Go 的 switch 和 C/Java 的有几个重要区别:

1. 默认不穿透

在 C/Java 里,每个 case 后面必须写 break,否则会继续执行下一个 case。Go 不需要:

switch x {
case 1:
    fmt.Println("一")
    // 自动 break,不会执行 case 2
case 2:
    fmt.Println("二")
}

Go 默认每个 case 执行完就跳出,不会穿透到下一个 case。

2. case 值不必是常量

func main() {
    x := rand.Intn(10)
    switch x {
    case 1:
        fmt.Println("一")
    case x * 2:
        fmt.Println("等于两倍")  // case 可以是表达式
    default:
        fmt.Println("其他")
    }
}

3. case 值不必是整数

switch "hello" {
case "hi":
    fmt.Println("hi")
case "hello":
    fmt.Println("hello")  // 匹配这个
default:
    fmt.Println("unknown")
}

字符串、浮点数等都可以作为 case 值。

case 多值匹配

一个 case 可以匹配多个值,用逗号分隔:

switch day {
case "Saturday", "Sunday":
    fmt.Println("周末")
default:
    fmt.Println("工作日")
}

只要 day 等于 "Saturday""Sunday",就会匹配这个 case。

无表达式 switch

switch 后面可以不写表达式,相当于 switch true,每个 case 是一个条件:

score := 85

switch {
case score >= 90:
    fmt.Println("优秀")
case score >= 80:
    fmt.Println("良好")
case score >= 70:
    fmt.Println("中等")
case score >= 60:
    fmt.Println("及格")
default:
    fmt.Println("不及格")
}

这和 if-else if 链等价,但更整洁。当你在判断一个值的多个范围时,用无表达式 switch 比一堆 if-else 更清晰。

fallthrough

如果你确实想穿透到下一个 case,用 fallthrough

switch x {
case 1:
    fmt.Println("一")
    fallthrough
case 2:
    fmt.Println("二")
    fallthrough
case 3:
    fmt.Println("三")
}

如果 x 是 1,输出:



fallthrough无条件跳到下一个 case 的代码块,不管下一个 case 的条件是否匹配。

Warning

fallthrough 必须是 case 块的最后一条语句。不能放在中间,也不能用在 case 的最后(因为没有下一个 case 了)。

// 报错
switch x {
case 1:
    fallthrough
    fmt.Println("这行不会执行")  // fallthrough 后面不能有语句
}
Tip

实际开发中很少用 fallthrough。如果你发现需要用它,先想想是不是设计有问题。大部分场景下,多个 case 合并或函数调用能更好地解决问题。

switch 带初始化语句

if 一样,switch 也可以带初始化语句:

switch num := computeValue(); num {
case 0:
    fmt.Println("零")
case 1:
    fmt.Println("一")
default:
    fmt.Println("其他")
}

num 的作用域只在 switch 块内。

switch 求值顺序

case 从上到下依次匹配,匹配到就停止:

switch x {
case 0:
    fmt.Println("零")
case f():  // 如果 x==0,f() 不会被调用
    fmt.Println("f()")
}

如果 x 等于 0,第一个 case 就匹配了,f() 不会被调用。这个特性可以用来做短路优化。

实际示例

根据类型判断

func describe(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("整数:%d\n", v)
    case string:
        fmt.Printf("字符串:%s\n", v)
    case bool:
        fmt.Printf("布尔:%t\n", v)
    default:
        fmt.Printf("未知类型:%T\n", v)
    }
}

这种写法叫类型 switch,用于判断接口值的实际类型。接口和类型断言后面章节会详细讲。

根据星期几做不同操作

func dailyTask(day string) {
    switch day {
    case "Monday":
        fmt.Println("开周会")
    case "Tuesday", "Wednesday", "Thursday":
        fmt.Println("写代码")
    case "Friday":
        fmt.Println("代码评审")
    case "Saturday", "Sunday":
        fmt.Println("休息")
    default:
        fmt.Println("无效的星期")
    }
}

处理 HTTP 状态码

func handleStatus(code int) string {
    switch code {
    case 200:
        return "OK"
    case 301:
        return "Moved Permanently"
    case 400:
        return "Bad Request"
    case 404:
        return "Not Found"
    case 500:
        return "Internal Server Error"
    default:
        return "Unknown"
    }
}

switch 和 if-else if 的选择

场景推荐
同一个变量的多个具体值switch
不同的条件表达式if-else if
范围判断(大于、小于)无表达式 switch 或 if-else if
类型判断类型 switch(必须用 switch)
// 用 switch 更好
switch month {
case 1, 2, 3:
    fmt.Println("第一季度")
case 4, 5, 6:
    fmt.Println("第二季度")
}

// 用 if-else 更好
if age < 18 {
    // ...
} else if hasPermission {
    // ...
} else if isAdmin {
    // ...
}

常见问题

忘了写 default

不是必须写 default,但建议写上,特别是当你的 switch 应该覆盖所有可能值时。default 可以帮你发现遗漏的情况。

case 重复

switch x {
case 1:
    // ...
case 1:  // 报错:duplicate case
    // ...
}

同一个值不能出现在两个 case 里。

fallthrough 误用

switch x {
case 1:
    fmt.Println("一")
    fallthrough
case 2:
    fmt.Println("二")
}

如果 x 不是 1 而是 2,只会输出 “二”,fallthrough 不会往回跳。fallthrough 只从匹配的 case 往下穿透。

学完这节你能做什么

  • 写基本的 switch 语句
  • 用 case 多值匹配简化代码
  • 用无表达式 switch 替代 if-else 链
  • 理解 fallthrough 的行为和限制
  • 知道什么时候用 switch,什么时候用 if

下一节讲 for 循环。