switch语句 #

一、基本语法 #

go
switch 表达式 {
case 值1:
    // 执行体
case 值2:
    // 执行体
default:
    // 默认执行体
}

二、基本用法 #

2.1 简单switch #

go
day := 3

switch day {
case 1:
    fmt.Println("星期一")
case 2:
    fmt.Println("星期二")
case 3:
    fmt.Println("星期三")
case 4:
    fmt.Println("星期四")
case 5:
    fmt.Println("星期五")
case 6:
    fmt.Println("星期六")
case 7:
    fmt.Println("星期日")
default:
    fmt.Println("无效的日期")
}

2.2 无穿透 #

Go的switch默认不穿透,不需要break:

go
n := 2

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

2.3 多值匹配 #

go
day := 6

switch day {
case 1, 2, 3, 4, 5:
    fmt.Println("工作日")
case 6, 7:
    fmt.Println("周末")
default:
    fmt.Println("无效的日期")
}

三、无表达式switch #

3.1 基本语法 #

go
switch {
case 条件1:
    // 执行体
case 条件2:
    // 执行体
default:
    // 默认执行体
}

3.2 示例 #

go
score := 85

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

四、fallthrough穿透 #

4.1 基本用法 #

使用fallthrough强制执行下一个case:

go
n := 1

switch n {
case 1:
    fmt.Println("一")
    fallthrough
case 2:
    fmt.Println("二")
    fallthrough
case 3:
    fmt.Println("三")
}
// 输出:一 二 三

4.2 注意事项 #

  • fallthrough不会判断下一个case条件
  • 只能放在case块最后
go
switch n {
case 1:
    fmt.Println("一")
    fallthrough
    fmt.Println("不会执行")  // 错误:fallthrough后不能有语句
case 2:
    fmt.Println("二")
}

五、初始化语句 #

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

六、类型switch #

6.1 基本语法 #

用于判断接口变量的实际类型:

go
switch v := i.(type) {
case 类型1:
    // v是类型1
case 类型2:
    // v是类型2
default:
    // 未知类型
}

6.2 示例 #

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

printType(42)       // 整数: 42
printType("hello")  // 字符串: hello
printType(true)     // 布尔值: true

6.3 多类型匹配 #

go
switch v := i.(type) {
case int, int32, int64:
    fmt.Printf("整数类型: %v\n", v)
case float32, float64:
    fmt.Printf("浮点类型: %v\n", v)
default:
    fmt.Printf("其他类型: %T\n", v)
}

七、实际应用 #

7.1 命令处理 #

go
func handleCommand(cmd string) {
    switch cmd {
    case "start":
        startService()
    case "stop":
        stopService()
    case "restart":
        stopService()
        startService()
    case "status":
        showStatus()
    default:
        fmt.Println("未知命令")
    }
}

7.2 HTTP路由 #

go
func handleRequest(method string) {
    switch method {
    case "GET":
        handleGet()
    case "POST":
        handlePost()
    case "PUT":
        handlePut()
    case "DELETE":
        handleDelete()
    default:
        fmt.Println("不支持的请求方法")
    }
}

7.3 状态机 #

go
type State int

const (
    StateIdle State = iota
    StateConnecting
    StateConnected
    StateDisconnecting
)

func (s State) String() string {
    switch s {
    case StateIdle:
        return "空闲"
    case StateConnecting:
        return "连接中"
    case StateConnected:
        return "已连接"
    case StateDisconnecting:
        return "断开中"
    default:
        return "未知状态"
    }
}

7.4 错误处理 #

go
func handleError(err error) {
    switch e := err.(type) {
    case *os.PathError:
        fmt.Printf("路径错误: %v\n", e)
    case *net.OpError:
        fmt.Printf("网络错误: %v\n", e)
    default:
        fmt.Printf("其他错误: %v\n", e)
    }
}

八、switch vs if-else #

8.1 使用switch的场景 #

  • 多个固定值比较
  • 类型判断
  • 可读性更好
go
// switch更清晰
switch day {
case 1, 2, 3, 4, 5:
    fmt.Println("工作日")
case 6, 7:
    fmt.Println("周末")
}

8.2 使用if-else的场景 #

  • 范围判断
  • 复杂条件
  • 条件之间有依赖
go
// if-else更适合
if score >= 90 {
    fmt.Println("优秀")
} else if score >= 80 {
    fmt.Println("良好")
} else if score >= 60 {
    fmt.Println("及格")
}

九、常见错误 #

9.1 重复case #

go
switch n {
case 1:
    fmt.Println("一")
case 1:  // 错误:重复的case
    fmt.Println("一")
}

9.2 类型不匹配 #

go
var n int = 1
switch n {
case "1":  // 错误:类型不匹配
    fmt.Println("一")
}

9.3 fallthrough误用 #

go
switch n {
case 1:
    fallthrough  // 错误:后面没有case
}

十、最佳实践 #

10.1 保持简洁 #

go
// 好
switch status {
case StatusOK:
    return "OK"
case StatusError:
    return "Error"
}

// 不好
switch {
case status == StatusOK:
    return "OK"
case status == StatusError:
    return "Error"
}

10.2 使用default #

go
switch n {
case 1:
    fmt.Println("一")
case 2:
    fmt.Println("二")
default:
    fmt.Println("其他")
}

10.3 避免过多case #

go
// 如果case太多,考虑使用map
var dayNames = map[int]string{
    1: "星期一",
    2: "星期二",
    // ...
}

fmt.Println(dayNames[day])

十一、总结 #

switch语句要点:

特性 说明
无穿透 默认不穿透,不需要break
多值匹配 case可以有多个值
无表达式 switch可以不带表达式
类型switch 判断接口实际类型
fallthrough 强制穿透到下一个case

关键点:

  1. 无穿透:Go的switch默认不穿透
  2. 多值匹配:case可以匹配多个值
  3. 类型switch:使用v := i.(type)判断类型
  4. fallthrough:强制穿透,但很少使用
  5. 初始化语句:可以在switch后添加初始化语句

准备好学习循环语句了吗?让我们进入下一章!

最后更新:2026-03-26