Switch 是 Go 語言中一種多路條件語句吼旧,一般搭配 case 語句使用乌助。
執(zhí)行邏輯
一個(gè) switch case 條件結(jié)構(gòu)如下所示:
switch simpleStatement; condition {
case expression1,expression2:
statements
case expression3:
statements
default:
statements
}
和 if 語句類似,switch 語句也可以在條件語句之前執(zhí)行一段簡短的表達(dá)式(可以用于很方便的控制變量的作用域)死姚,switch case 開始執(zhí)行時(shí)苛蒲,會先執(zhí)行這一個(gè)表達(dá)式(空也算一種),然后計(jì)算出條件語句的值筑煮,接著按從上到下辛蚊,從左到右的順序一個(gè)一個(gè)的執(zhí)行 case 語句的條件表達(dá)式,如果值相等的話就會進(jìn)入執(zhí)行 case 條件下對應(yīng)的語句咆瘟。
如果所有的 case 條件都沒有能匹配上的話嚼隘,然后就會嘗試執(zhí)行 default 下對應(yīng)的邏輯。
case 條件合并
如果有時(shí)候多個(gè) case 條件對應(yīng)的處理邏輯是一樣的話袒餐,Go 語言中的 case 條件是可以合并的飞蛹,多個(gè)條件用逗號分隔,判斷順序是從左到右灸眼。
func main() {
switch runtime.GOOS {
case "linux","darwin" :
println("unix環(huán)境")
case "windows":
println("windows環(huán)境")
}
}
支持的類型
不像 Java 只支持整型進(jìn)行判斷(其他類型都是通過轉(zhuǎn)化成整型實(shí)現(xiàn)的)卧檐,Go 里的 switch 的參數(shù)是一個(gè)表達(dá)式,支持任何類型進(jìn)行比較焰宣,甚至 switch 的條件還可以是一個(gè)空的霉囚,這個(gè)時(shí)候等價(jià)于 switch true,可以用于簡化多個(gè) if 條件的場景匕积。
func price(weight int) int {
if weight > 10 {
return 100
} else if weight > 8 {
return 110
} else if weight > 5 {
return 120
} else {
return 150
}
}
比如上方這個(gè)多重 if else 判斷邏輯就可以用下方這個(gè)無參數(shù)的 switch case 語句替代:
func price(weight int) int {
switch {
case weight>10:
return 100
case weight>8:
return 110
case weight>5:
return 120
default:
return 150
}
}
隱式 break & fallthrough
Go 語言中匹配到一個(gè) case 條件執(zhí)行完對應(yīng)的邏輯之后就會跳出這個(gè) switch 語句盈罐,等價(jià)于每個(gè) case 處理邏輯之后都加了一個(gè)隱式的 break 語句。如果不想要隱式退出的話可以使用 fallthrough 語句來繼續(xù)下一個(gè) case 的處理邏輯闪唆。
隱式 break:
func main() {
switch runtime.GOOS {
case "linux","darwin" :
println("unix環(huán)境")
case "windows":
println("window環(huán)境")
default:
println("什么都不是")
}
}
輸出:
windows環(huán)境
強(qiáng)行 fallthrough:
func main() {
switch runtime.GOOS {
case "linux","darwin" :
println("unix環(huán)境")
fallthrough
case "windows":
println("windows環(huán)境")
fallthrough // 會繼續(xù)執(zhí)行下一個(gè)語句
default:
println("什么都不是")
}
}
輸出:
windows環(huán)境
什么都不是
不過這一點(diǎn)就和很多其他編程語言正好相反盅粪,比如:Java、C++悄蕾。Java 和 C++ 中的 switch case 都是隱式 fallthrough票顾,而break 則需要顯示調(diào)用,這兩種方式各有利弊吧,還是看不同的使用場景奠骄,不過 Java 12 中也加入了對于隱式 break 的支持豆同。
另外 Go 語言中也是可以顯示調(diào)用 break 提前跳出的,用法和循環(huán)語句中的 break 是一樣的含鳞,也可以加標(biāo)簽指定跳出具體哪一段邏輯影锈。
break 顯式跳出:
func main() {
x := []int{1,2,3,4,5}
for _, i := range x {
switch {
case i>0 :
if i > 1 && i < 3 {
break
}
println(i)
}
}
}
輸出:
1
3
4
5
指定標(biāo)簽跳出 for 循環(huán):
func main() {
x := []int{1,2,3,4,5}
a:
for _, i := range x {
switch {
case i>0 :
if i > 1 && i < 3 {
break a
}
println(i)
}
}
}
輸出:
1
Type Switch
Go 語言中的 switch 條件還可以是一種類型,這個(gè)特性在一個(gè)變量可能是多種類型時(shí)非常有用民晒,雖然也可以 if else 加上類型斷言來實(shí)現(xiàn):
func main() {
i := interface{}(123)
if _,ok := i.(int);ok{
println("int")
}else if _,ok := i.(int64);ok {
println("int64")
}else if _,ok := i.(string);ok {
println("string")
}
}
但是用 Type Switch 的話代碼會更簡潔一些精居,比如上面的邏輯用 Type Switch 重寫:
func main() {
i := interface{}(123)
switch i.(type) {
case int:
println("int")
case int64:
println("int64")
case float64:
println("float64")
}
}
輸出:
int
(注:這里 123 是 int 類型而不是 int64,因?yàn)樵谏昝髯兞繒r(shí)并沒有指定具體類型潜必,編譯器會自行推導(dǎo)類型靴姿,而 int 是無類型整形的默認(rèn)類型。)
同時(shí) Type Switch 可以給賦值給一個(gè)變量磁滚,這個(gè)變量在不同的 case 中會變成對應(yīng) case 條件的類型(在合并了 case 語句之后會失效)
func main() {
var i interface{}
switch x := i.(type) {
case error:
x.Error()
case fmt.Stringer:
x.String()
}
}
原文發(fā)表于:https://huweicai.com/go-switch/