跳转到主要内容
模块 2 · 第 4 课(共 5)课程中的9/50~10 min
模块课程(4/5)

惯用开关

Go 的 switch 比 C/Java 的更符合人体工程学:每个 case 都有其 自己的隐式块(无需编写 break ),可以分组 带逗号的多个值,以及不带表达式的 switch 的行为 就像一个更具可读性的 if/else if 链。

开启一个值

Go
giorno := "mar"
switch giorno {
case "lun", "mar", "mer", "gio", "ven":
    fmt.Println("feriale")
case "sab", "dom":
    fmt.Println("weekend")
default:
    fmt.Println("sconosciuto")
}

case 接受用逗号分隔的多个值,并且 没有隐式 Fallthrough:一旦执行了一个案例,开关就退出。

无条件切换

如果省略表达式,开关将计算 true 并且每个 case 都是一个 bool 条件。这是长 if/else if 链的惯用替代方案:

Go
switch {
case x < 0:
    fmt.Println("negativo")
case x == 0:
    fmt.Println("zero")
case x < 10:
    fmt.Println("piccolo")
default:
    fmt.Println("grande")
}

初始化语句

与 if 一样,switch 也接受 init 语句:

Go
switch n := len(s); {
case n == 0:
    fmt.Println("vuoto")
case n > 100:
    fmt.Println("lungo")
default:
    fmt.Println("ok")
}

n 仅存在于交换机内部。

显式 fallthrough

如果你确实希望执行落入下一种情况,你必须这样写:

Go
switch 1 {
case 1:
    fmt.Println("uno")
    fallthrough
case 2:
    fmt.Println("due")  // anche questo viene stampato
case 3:
    fmt.Println("tre")  // questo no
}

类型开关(预览)

它可以让您根据接口的动态类型进行区分 值。我们将在接口模块中深入介绍它:

Go
var i interface{} = "ciao"
switch v := i.(type) {
case int:
    fmt.Println("int:", v)
case string:
    fmt.Println("string:", v)
default:
    fmt.Printf("tipo %T\n", v)
}

尝试一下

锻炼#go.m2.l4.e1
尝试:0加载中...

对于 lun/mar/mer/gio/ven 打印“feriale”,否则打印“weekend”,使用 g 值的开关。

正在加载编辑器...
显示提示

将 5 个工作日分组为一个案例,并用逗号分隔。

3 次尝试后可用的解决方案

锻炼#go.m2.l4.e2
尝试:0加载中...

使用不带条件的开关根据 x 打印“neg”、“zero”或“pos”。

正在加载编辑器...
显示提示

`switch` 之后没有任何表达式,只有 `{`。

3 次尝试后可用的解决方案

Quiz#go.m2.l4.e3
准备好

这个程序打印什么?

Go
switch 1 {
case 1:
    fmt.Print("a")
case 2:
    fmt.Print("b")
}
答案选项

回顾

  • case 接受以逗号分隔的多个值。
  • 无隐式失败:每种情况都有其自己的隐式 break。
  • 没有表达式的 switch { ... } = 更具可读性的 if/else if 链。
  • 初始化语句:switch x := f(); { ... },范围仅限于块。
  • fallthrough 存在但很少见;进入下一个案例而不评估其条件。
  • 键入开关 v := i.(type) 以根据动态类型(接口模块)进行区分。