go switch分支
switch
是一个条件语句,用于将一个表达式的求值结果与可能的值的列表进行匹配,并根据匹配结果执行相应的代码。可以认为switch语句是编写多个if-else子句的替代方式。
举例是说明问题最好的方式,让我们写一个简单的程序,输入手指编号,输出对应的手指名称:)。例如0表示拇指,1表示食指等。
packagemain import( "fmt" ) funcmain(){ finger:=4 switchfinger{ case1: fmt.Println("Thumb") case2: fmt.Println("Index") case3: fmt.Println("Middle") case4: fmt.Println("Ring") case5: fmt.Println("Pinky") } }12345678910111213141516171819202122
在上面的程序中,case
语句依次(从上到下)求值并与finger
进行匹配,直到找到第一个与finger
匹配的case
,并执行其中的代码。在这里finger
的值为4,因此打印Ring
。
多个有相同值的case
是不允许的。如果你运行下面的程序,编译将会报错:duplicatecase4inswitch
。
packagemain import( "fmt" ) funcmain(){ finger:=4 switchfinger{ case1: fmt.Println("Thumb") case2: fmt.Println("Index") case3: fmt.Println("Middle") case4: fmt.Println("Ring") case4://duplicatecase fmt.Println("AnotherRing") case5: fmt.Println("Pinky") } }123456789101112131415161718192021222324
defaultcase
我们每只手只有5根手指,但是如果我们输入一个错误的手指序号会发生什么呢?这里就要用到default
语句了。当没有其他case
匹配时,将执行default
语句。
packagemain import( "fmt" ) funcmain(){ switchfinger:=8;finger{//fingerisdeclaredinswitch case1: fmt.Println("Thumb") case2: fmt.Println("Index") case3: fmt.Println("Middle") case4: fmt.Println("Ring") case5: fmt.Println("Pinky") default://defaultcase fmt.Println("incorrectfingernumber") } }12345678910111213141516171819202122
在上面的程序中,finger
的值为8,它不匹配任何case
,因此打印incorrectfingernumber
。default
语句不必放在switch
语句的最后,而可以放在switch
语句的任何位置。
你也许发现了另外一个小的改变,就是将finger
声明在了switch
语句中。switch
语句可以包含一个可选的语句,该语句在表达式求值之前执行。在switchfinger:=8;finger
这一行中,finger
首先被声明,然后作为表达式被求值。这种方式(译者注:在switch语句中声明变量的方式)声明的finger
只能在switch
语句中访问。
包含多个表达式的case
可以在一个case
中包含多个表达式,每个表达式用逗号分隔。
packagemain import( "fmt" ) funcmain(){ letter:="i" switchletter{ case"a","e","i","o","u"://multipleexpressionsincase fmt.Println("vowel") default: fmt.Println("notavowel") } }123456789101112131415
上面的程序检测letter
是否是元音。case"a","e","i","o","u":
这一行匹配所有的元音。程序的输出为:vowel
。
没有表达式的switch
switch
中的表达式是可选的,可以省略。如果省略表达式,则相当于switchtrue
,这种情况下会将每一个case
的表达式的求值结果与true
做比较,如果相等,则执行相应的代码。
packagemain import( "fmt" ) funcmain(){ num:=75 switch{//expressionisomitted casenum>=0&&num<=50: fmt.Println("numisgreaterthan0andlessthan50") casenum>=51&&num<=100: fmt.Println("numisgreaterthan51andlessthan100") casenum>=101: fmt.Println("numisgreaterthan100") } }123456789101112131415161718
在上面的程序中,switch
后面没有表达式因此被认为是switchtrue
并对每一个case
表达式的求值结果与true
做比较。casenum>=51&&num<=100:
的求值结果为true
,因此程序输出:numisgreaterthan51andlessthan100
。这种类型的switch
语句可以替代多重ifelse
子句。
fallthrough
在Go中执行完一个case
之后会立即退出switch
语句。fallthrough
语句用于标明执行完当前case
语句之后按顺序执行下一个case
语句。
让我们写一个程序来了解fallthrough
。下面的程序检测number
是否小于50,100或200。例如,如果我们输入75,程序将打印75小于100和200,这是通过fallthrough
语句实现的。
packagemain import( "fmt" ) funcnumber()int{ num:=15*5 returnnum } funcmain(){ switchnum:=number();{//numisnotaconstant casenum<50: fmt.Printf("%dislesserthan50\n",num) fallthrough casenum<100: fmt.Printf("%dislesserthan100\n",num) fallthrough casenum<200: fmt.Printf("%dislesserthan200",num) } }12345678910111213141516171819202122232425
switch
与case
中的表达式不必是常量,他们也可以在运行时被求值。在上面的程序中num
初始化为函数number()
的返回值。程序首先对switc
h中的表达式求值,然后依次对每一个case
中的表达式求值并与true
做匹配。匹配到casenum<100:
时结果是true
,因此程序打印:75islesserthan100
,接着程序遇到fallthrough
语句,因此继续执行下一个case
中的语句,打印:75islesserthan200
。最后的输出如下:
75islesserthan100 75islesserthan20012
fallthrough
必须是case
语句块中的最后一条语句。如果它出现在语句块的中间,编译器将会报错:fallthroughstatementoutofplace
。
还有一种switch
语句叫做typeswitch
,我们将在学习接口时介绍它。