什么是 switch 语句?
switch 是一个条件语句,它计算表达式并将其与可能匹配的列表进行比较并执行相应的代码块。它可以被认为是替换复杂if else
从句的惯用方式。
Example
一个示例程序好过说一百字。让我们从一个简单的示例开始,它将手指编号作为输入并输出该手指的名称:)。例如,1 是Thumb,2 是Index,依此类推。
1 | package main |
在上述程序switch finger
中的第 10 行比较finger
每个case
语句的值。从上到下对案例进行评估,并执行与表达式匹配的第一个案例。在这种情况下,finger
有一个值4
,因此输出:
1 | Finger 4 is Ring |
重复的case不被允许
不允许出现具有相同常数值的重复case。如果你尝试运行下面的程序,编译器会报下列错
./prog.go:19:7: duplicate case 4 in switch previous case at ./prog.go:17:7
1 | package main |
Default case
我们手上只有 5 根手指。如果我们输入错误的手指编号会发生什么?这是就是default
出现的地方。当其他情况都不匹配时,将执行default
。
1 | package main |
在上面的程序中finger
为8
,它与任何情况都不匹配,因此在default
下打印incorrect finger number
。没有必要将default
作为 switch 语句中的最后一种情况。它可以出现在switch
中的6任何位置。
您可能还注意到finger
. 它在 switch 中声明。switch 可以包含一个可选语句,该语句在计算表达式之前执行。在第8行finger
先声明再在表达式中使用。在这种情况下,finger
的作用域仅限于 switch
块。
一个case中有多个常量表达式
通过用逗号分隔多个表达式,可以在一个 case 中包含多个表达式。
1 | package main |
上面的程序判断letter
是否是元音。11行中的代码case "a", "e", "i", "o", "u":
匹配任何元音。因为i
是元音,所以这个程序打印:
1 | Letter i is a vowel |
Expressionless switch
switch 中的表达式是可选的,可以省略。如果表达式被省略,则开关被认为是switch true
,并且每个case
表达式都被评估为真,并执行相应的代码块。
1 | package main |
在上面的程序中,switch 中没有表达式,因此它被认为是 true,并且每个 case 都被评估。第12行case num >= 51 && num <= 100:
是true
,程序打印:
1 | 75 is greater than 51 and less than 100 |
这种类型的 switch 可以被认为是多个if else
子句的替代方案。
Fallthrough
在 Go 中,一个 case 执行后立即脱离 switch 语句。fallthrough
语句用于将控制转移到在已执行的案例之后相邻出现案例的第一条语句。
让我们编写一个程序来理解fallthrough。我们的程序将检查输入的数字是否小于 50、100 或 200。例如,如果我们输入 75,程序将打印 75 小于 100 和 200。我们将使用fallthrough
.
1 | package main |
Switch 和 case 表达式不必只是常量。它们也可以在运行时进行评估。在上面的程序中num
在第 14 行中被初始化为函数行号 18的返回值number()
。控制进入switch内部并评估每条case。第 18 行的case num < 100:
语句为真,程序打印75 is lesser than 100
。下一条语句是fallthrough
。当fallthrough
遇到时,控件移动到下一个案例的第一条语句并打印75 is lesser than 200
。程序的输出是
1 | 75 is lesser than 100 |
fallthrough
应该是case
中的最后一条语句。如果它出现在中间的某个地方,编译器会报错fallthrough statement out of place
.
当case为false的时候Fallthrough也会继续生效
使用fallthrough
时需要考虑一个微妙之处。即使case评估为假,Fallthrough也会继续生效。
请考虑以下程序。
1 | package main |
在上面的程序中,num
是 25,它小于 50,因此第 9 行评估为真。fallthrough出现在第 11 行中。12行号中的下一个案例case num > 100:
是错误的,因为 num < 100。但是 fallthrough 没有考虑到这一点。即使案例评估为假,Fallthrough也会继续生效。
上面的程序将打印:
1 | 25 is lesser than 50 |
因此,请确保您了解在使用 fallthrough 时您在做什么。
还有一件事是fallthrough
不能在最后一种情况下使用 switch,因为没有更多的情况可以通过。如果fallthrough
在最后一种情况下存在,则会导致以下编译错误。
1 | cannot fallthrough final case in switch |
Breaking switch
该break
语句可用于在 switch 完成之前提前终止它。让我们将上面的示例修改为一个人为的示例,以了解 break 的工作原理。
让我们添加一个条件,如果num
小于 0,则switch应该终止。
1 | package main |
在上面的程序num
中是-5
. 当控件到达第 10 行的 if 语句时,条件满足,因为 num < 0。break 语句在 switch 完成之前终止 switch,并且程序不打印任何内容:)。
打破外部 for 循环
当 switch case 在for 循环中时,可能需要提前终止 for 循环。这可以通过label标记 for 循环并在 switch 语句中使用该标签中断 for 循环来完成。让我们看一个例子。
让我们编写一个程序来生成一个随机偶数。
我们将创建一个无限 for 循环并使用 switch case 来确定生成的随机数是否为偶数。如果是偶数,则打印生成的数字并使用其标签终止 for 循环。该rand
包中函数Intn
的功能用于生成非负伪随机数。
1 | package main |
在上面的程序中,使用标签在第 9 行标记randloop
。for 循环第 11 行中的Intn
函数生成一个介于 0 和 99 之间(不包括 100)的随机数。如果生成的数字是偶数,则for循环在第 14 行中断。。
该程序打印:
1 | Generated even number 18 |
请注意,如果使用不带标签的 break 语句,则只会中断 switch 语句,for循环将继续运行。因此,标记循环并在 switch 内的 break 语句中使用它是中断外部 for 循环的必要条件。
这将我们带到本教程的结尾。还有另一种类型的 switch 称为type switch。当我们学习接口时,我们会研究这个。