相比較 C 和 Java 等其它語言而言,Go 語言中的 switch 結(jié)構(gòu)使用上更加靈活。它接受任意形式的表達(dá)式:
switch var1 {
case val1:
...
case val2:
...
default:
...
}
變量 var1 可以是任何類型,而 val1 和 val2 則可以是同類型的任意值。類型不被局限于常量或整數(shù),但必須是相同的類型;或者最終結(jié)果為相同類型的表達(dá)式。前花括號(hào) {
必須和 switch 關(guān)鍵字在同一行。
您可以同時(shí)測試多個(gè)可能符合條件的值,使用逗號(hào)分割它們,例如:case val1, val2, val3
。
每一個(gè) case
分支都是唯一的,從上至下逐一測試,直到匹配為止。( Go 語言使用快速的查找算法來測試 switch 條件與 case 分支的匹配情況,直到算法匹配到某個(gè) case 或者進(jìn)入 default 條件為止。)
一旦成功地匹配到某個(gè)分支,在執(zhí)行完相應(yīng)代碼后就會(huì)退出整個(gè) switch 代碼塊,也就是說您不需要特別使用 break
語句來表示結(jié)束。
因此,程序也不會(huì)自動(dòng)地去執(zhí)行下一個(gè)分支的代碼。如果在執(zhí)行完每個(gè)分支的代碼后,還希望繼續(xù)執(zhí)行后續(xù)分支的代碼,可以使用 fallthrough
關(guān)鍵字來達(dá)到目的。
因此:
switch i {
case 0: // 空分支,只有當(dāng) i == 0 時(shí)才會(huì)進(jìn)入分支
case 1:
f() // 當(dāng) i == 0 時(shí)函數(shù)不會(huì)被調(diào)用
}
并且:
switch i {
case 0: fallthrough
case 1:
f() // 當(dāng) i == 0 時(shí)函數(shù)也會(huì)被調(diào)用
}
在 case ...:
語句之后,您不需要使用花括號(hào)將多行語句括起來,但您可以在分支中進(jìn)行任意形式的編碼。當(dāng)代碼塊只有一行時(shí),可以直接放置在 case
語句之后。
您同樣可以使用 return
語句來提前結(jié)束代碼塊的執(zhí)行。當(dāng)您在 switch 語句塊中使用 return
語句,并且您的函數(shù)是有返回值的,您還需要在 switch 之后添加相應(yīng)的 return
語句以確保函數(shù)始終會(huì)返回。
可選的 default
分支可以出現(xiàn)在任何順序,但最好將它放在最后。它的作用類似與 if-else
語句中的 else
,表示不符合任何已給出條件時(shí),執(zhí)行相關(guān)語句。
示例 5.4 switch1.go:
package main
import "fmt"
func main() {
var num1 int = 100
switch num1 {
case 98, 99:
fmt.Println("It's equal to 98")
case 100:
fmt.Println("It's equal to 100")
default:
fmt.Println("It's not equal to 98 or 100")
}
}
輸出:
It's equal to 100
在第 12.1 節(jié),我們會(huì)使用 switch 語句判斷從鍵盤輸入的字符(詳見第 12.2 節(jié)的 switch.go)。switch 語句的第二種形式是不提供任何被判斷的值(實(shí)際上默認(rèn)為判斷是否為 true),然后在每個(gè) case 分支中進(jìn)行測試不同的條件。當(dāng)任一分支的測試結(jié)果為 true 時(shí),該分支的代碼會(huì)被執(zhí)行。這看起來非常像鏈?zhǔn)降?if-else
語句,但是在測試條件非常多的情況下,提供了可讀性更好的書寫方式。
switch {
case condition1:
...
case condition2:
...
default:
...
}
例如:
switch {
case i < 0:
f1()
case i == 0:
f2()
case i > 0:
f3()
}
任何支持進(jìn)行相等判斷的類型都可以作為測試表達(dá)式的條件,包括 int、string、指針等。
示例 5.4 switch2.go:
package main
import "fmt"
func main() {
var num1 int = 7
switch {
case num1 < 0:
fmt.Println("Number is negative")
case num1 > 0 && num1 < 10:
fmt.Println("Number is between 0 and 10")
default:
fmt.Println("Number is 10 or greater")
}
}
輸出:
Number is between 0 and 10
switch 語句的第三種形式是包含一個(gè)初始化語句:
switch initialization {
case val1:
...
case val2:
...
default:
...
}
這種形式可以非常優(yōu)雅地進(jìn)行條件判斷:
switch result := calculate(); {
case result < 0:
...
case result > 0:
...
default:
// 0
}
在下面這個(gè)代碼片段中,變量 a 和 b 被平行初始化,然后作為判斷條件:
switch a, b := x[i], y[j]; {
case a < b: t = -1
case a == b: t = 0
case a > b: t = 1
}
switch 語句還可以被用于 type-switch(詳見第 11.4 節(jié))來判斷某個(gè) interface 變量中實(shí)際存儲(chǔ)的變量類型。
問題 5.1:
請(qǐng)說出下面代碼片段輸出的結(jié)果:
k := 6
switch k {
case 4: fmt.Println("was <= 4"); fallthrough;
case 5: fmt.Println("was <= 5"); fallthrough;
case 6: fmt.Println("was <= 6"); fallthrough;
case 7: fmt.Println("was <= 7"); fallthrough;
case 8: fmt.Println("was <= 8"); fallthrough;
default: fmt.Println("default case")
}
練習(xí) 5.2: season.go:
寫一個(gè) Season 函數(shù),要求接受一個(gè)代表月份的數(shù)字,然后返回所代表月份所在季節(jié)的名稱(不用考慮月份的日期)。