主要内容:
7.1 switch语句概述7.2 switch语法 7.3 switch示例 7.4 default case 7.5 一个case中含有多个表达式 7.6 无表达式的switch 7.7 fallthrough语句7.8 break语句
7.1 switch语句概述
我们上一节学习了if语句。if语句很有用,但是有些情况下,if语句用起来会比较繁琐。Go还提供了一个相关的语句——switch语句。
下面我们通过例子说明switch语句。假定我们要编写一个程序,给定一个0-9的数字,需要打印出该数字的中文名。利用我们到目前为止已经学过的知识,你可以编写出这样的程序:
if i == 0 { fmt.Println("零")} else if i == 1 { fmt.Println("壹")} else if i == 2 { fmt.Println("贰")} else if i == 3 { fmt.Println("叁")} else if i == 4 { fmt.Println("肆")} else if i == 5 { fmt.Println("伍")} else if i == 6 { fmt.Println("陆")} else if i == 7 { fmt.Println("柒")} else if i == 8 { fmt.Println("捌")} else if i == 9 { fmt.Println("玖")} else { fmt.Println("其它")}这样写程序会比较枯燥。我们可以用switch语句来达到同样的目的。
switch i { case 0: fmt.Println("零") 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("柒") case 8: fmt.Println("捌") case 9: fmt.Println("玖") default: fmt.Println("其它")}switch语句以关键字switch开头,后接一个表达式(这里为i)、以及一系列的case语句。表达式的值将与关键字case后的表达式的值相比较。如果相等,则执行冒号:后面的语句。
与if语句类似,Go自上而下检查各个case的值,直到成功匹配第一个case。switch也支持缺省的情况,即当没有case匹配时,则执行default后面的语句块。
7.2 switch语法
对于多重的if-else语句,可以使用switch语句来代替。switch语句的语法形式示意如下:
switch 表达式 { case 表达式:语句 case 表达式:语句 ... default: 语句}执行完匹配的case中的语句块后,Go立即退出switch语句。如果所有的case表达式都不匹配的话,则执行default语句。
7.3 switch示例
package mainimport "fmt"func main() { i := 1 switch i { case 0: fmt.Println("零") 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("柒") case 8: fmt.Println("捌") case 9: fmt.Println("玖") }}运行该程序,结果为:
1壹
7.4 default case
在下例中,增加了default case。当没有任何case匹配switch表达式时,执行default case的语句块。
示例 - 使用循环和switch语句,打印0至9对应的汉字。
package mainimport "fmt"func main() { for i := 0; i <= 10; i++ { switch i { case 0: fmt.Println(i, "零") case 1: fmt.Println(i, "壹") case 2: fmt.Println(i, "贰") case 3: fmt.Println(i, "叁") case 4: fmt.Println(i, "肆") case 5: fmt.Println(i, "伍") case 6: fmt.Println(i, "陆") case 7: fmt.Println(i, "柒") case 8: fmt.Println(i, "捌") case 9: fmt.Println(i, "玖") default: fmt.Println(i, "其它") } }}注意,当i的值为10时,因为没有任何case与值i匹配,则执行default的打印语句。
该程序运行结果如下:
0零1壹2贰3叁4肆5伍6陆7柒8捌9玖10其它
7.5 一个case中含有多个表达式
Go的switch中的case子句不会自动穿透(fall through),但是case后的表达式可以是使用逗号分隔的列表。如下例所示,
func shouldEscape(c byte) bool { switch c { case , ?, &, =, #, +, %: return true } return false}一个case中可以含有多个表达式,只要有一个表达式的值与switch表达式值匹配的话,就执行该case中的语句。请看下例。
示例 - 打印一个字母是否为元音字母。
package mainimport ( "fmt")func main() { letter := "a" switch letter { case "a", "e", "i", "o", "u": // 一个case中含有多个表达式 fmt.Println(letter, "is a vowel") default: fmt.Println(letter, "is not a vowel") }}运行该程序,结果显示为:
a is a vowel
7.6 无表达式的switch
switch语句中的表达式可以省略。如果省略了表达式,则可以将这个switch语句看成switch true,将计算每个case的表达式。如果为true,则执行对应的case中的语句块。
相对于C语言,Go的switch语句更为通用。switch后接的表达式不需要是常量,甚至可以不是整型数。自上而下地计算case后的表达式的值,直到找到匹配。如果switch后面没有接表达式的话,则相当于后接true。通常,将if-else-if-else的链式语句改写为switch。
func unhex(c byte) byte { switch { case 0 <= c && c <= 9: return c - 0 case a <= c && c <= f: return c - a + 10 case A <= c && c <= F: return c - A + 10 } return 0}我们来看下面的示例。世界卫生组织WHO对于青年人和中年人等的最新定义如下:
未成年人 0-17岁青年人 18-65岁中年人 66-79岁老年人 80-99岁长寿老人 100岁以上编写程序,输入某人年龄,判断该人属于哪个年龄段。
示例 - 无表达式的switch语句
package mainimport ( "fmt")func main() { age := 75 switch { // switch后的表达式被省略 case age >= 0 && age <= 17: fmt.Println("未成年人") case age >= 18 && age <= 65: fmt.Println("青年人") case age >= 65 && age <= 79: fmt.Println("中年人") case age >= 80 && age <= 99: fmt.Println("老年人") case age >= 100: fmt.Println("长寿老人") }}该程序运行结果为:
中年人
再来看下面的示例,判断今天是平日还是周末,并判断现在的时刻是中午前还是中午后。
package mainimport "fmt"import "time"func main() { t := time.Now() switch t.Weekday() { case time.Saturday, time.Sunday: // 一个case中含有多个表达式 fmt.Println("Today is the weekend") default: // default case fmt.Println("Today is a weekday") } // 无表达式的switch switch { case t.Hour() < 12: fmt.Println("Its before noon now") default: fmt.Println("Its after noon now") }}7.7 fallthrough语句前面介绍的各种switch语句中,当执行完匹配的case中的语句块后,Go立即退出switch语句。如果使用了fallthrough语句,则Go不立即退出switch语句,而是将控制传送给下一个case语句。
示例 - fallthrough示例
package mainimport ( "fmt")func main() { switch i := 15 { case i < 10: fmt.Printf("%d is lesser than 10\n", i) fallthrough // 执行下一个case语句,而不是跳出switch语句 case i < 20: fmt.Printf("%d is lesser than 20\n", i) fallthrough // 执行下一个case语句,而不是跳出switch语句 case i < 30: fmt.Printf("%d is lesser than 30", i) }}运行该程序,结果显示如下:
15 is lesser than 2015 is lesser than 307.8 break语句由于Go的switch不会自动穿透,而C和Java等语言缺省都是自动穿透的,所以相比较而言,Go的switch语句中较少使用break语句。不过你仍然可以使用break语句来提取终止switch语句。有时,你希望跳出外围的循环,而不是switch语句。这种情况下你可以使用标签为循环做标记,然后使用break语句跳出该标签指定的循环。如下例所示,
Loop:for n := 0; n < len(src); n += size { switch { case src[n] < sizeOne: if validateOnly { break } size = 1 update(src[n]) case src[n] < sizeTwo: if n+1 >= len(src) { err = errShortInput break Loop } if validateOnly { break } size = 2 update(src[n] + src[n+1]<<shift) }}当然,continue语句也可以接收一个可选的标签,但是只适用于循环,而不适用于switch。
版权声明
本文仅代表作者观点,不代表xx立场。
本文系作者授权xxx发表,未经许可,不得转载。
发表评论