Go 語言基礎(chǔ) - switch語句
回復(fù)“Go語言”即可獲贈(zèng)Python從入門到進(jìn)階共10本電子書
你好,我是四哥。
上篇文章我們學(xué)習(xí)了 for 循環(huán)語句,這篇文章來學(xué)習(xí) switch 語句。
什么是 switch 語句
switch 是一個(gè)條件語句,用于計(jì)算條件表達(dá)式的值,判斷該值是否滿足 case 語句,如果匹配則會(huì)執(zhí)行相應(yīng)的代碼塊。是用來替換復(fù)雜 if-else 語句的常用方式。
示例
一個(gè)示例勝過千言萬語。我們來看一個(gè)簡單示例,該示例的輸入是手指的編號(hào),輸出是手機(jī)的名稱,比如:1 代表拇指,2 代表食指,等等。
package?main
import?(
????"fmt"
)
func?main()?{
????finger?:=?4
????fmt.Printf("Finger?%d?is?",?finger)
????switch?finger?{
????case?1:
????????fmt.Println("Thumb")
????case?2:
????????fmt.Println("Index")
????case?3:
????????fmt.Println("Middle")
????case?4:
????????fmt.Println("Ring")
????case?5:
????????fmt.Println("Pinky")
????}
}
執(zhí)行[1]
上面的代碼中,第 10 行的 switch finger 會(huì)從上只下將 finger 的值與每一個(gè) case 進(jìn)行比較,并執(zhí)行第一個(gè)匹配的 case 的代碼塊。我們這里示例中 finger 為 4,與 case 4 匹配,所以輸出:Finger 4 is Ring.
不允許有重復(fù)的 case
case 分支不允許有相同的常量值,如果你嘗試運(yùn)行下面的程序?qū)?huì)報(bào)錯(cuò):./prog.go:19:7: duplicate case 4 in switch previous case at ./prog.go:17:7
package?main
import?(
????"fmt"
)
func?main()?{
????finger?:=?4
????fmt.Printf("Finger?%d?is?",?finger)
????switch?finger?{
????case?1:
????????fmt.Println("Thumb")
????case?2:
????????fmt.Println("Index")
????case?3:
????????fmt.Println("Middle")
????case?4:
????????fmt.Println("Ring")
????case?4:?//duplicate?case
????????fmt.Println("Another?Ring")
????case?5:
????????fmt.Println("Pinky")
????}
}
執(zhí)行[2]
默認(rèn)的 case
一只手只有 5 個(gè)指頭,如果我們輸錯(cuò)了指頭編號(hào)會(huì)發(fā)生什么呢?這個(gè)時(shí)候 default 分支就可以派上用場(chǎng)了,如果其他分支都不匹配的話就會(huì)執(zhí)行 default 分支。
package?main
import?(
????"fmt"
)
func?main()?{
????switch?finger?:=?8;?finger?{
????case?1:
????????fmt.Println("Thumb")
????case?2:
????????fmt.Println("Index")
????case?3:
????????fmt.Println("Middle")
????case?4:
????????fmt.Println("Ring")
????case?5:
????????fmt.Println("Pinky")
????default:?//default?case
????????fmt.Println("incorrect?finger?number")
????}
}
執(zhí)行[3]
上面的代碼中,當(dāng) finger 等于 8 時(shí)不與任何 case 分支匹配,此時(shí)就會(huì)執(zhí)行 default 分支,所以輸出:incorrect finger number。在 switch 語句里,default 分支不是必須的,并且可以放在語句里的任何位置,不過我們一般都放在語句的最后面。
可能你已經(jīng)注意到聲明 finger 時(shí)的一點(diǎn)變化,它是在 switch 語句里面聲明的。switch 包含一個(gè)可選語句,該語句在常量表達(dá)式匹配之前被執(zhí)行。上面代碼的第 8 行,先聲明 finger,然后在條件表達(dá)式中被使用。這種情況下 finger 的作用局僅限于 switch 語句塊內(nèi)。
case 語句有多個(gè)表達(dá)式
case 語句中可以包括多個(gè)表達(dá)式,使用逗號(hào)分隔。
package?main
import?(
????"fmt"
)
func?main()?{
????letter?:=?"i"
????fmt.Printf("Letter?%s?is?a?",?letter)
????switch?letter?{
????case?"a",?"e",?"i",?"o",?"u":?//multiple?expressions?in?case
????????fmt.Println("vowel")
????default:
????????fmt.Println("not?a?vowel")
????}
}
執(zhí)行[4]
上面的代碼判斷 letter 是否是元音。第 11 行代碼的 case 分支用來匹配所有的元音,因?yàn)?"i" 是元音,所有輸出:
Letter?i?is?a?vowel
無條件表達(dá)式 switch 語句
switch 中的表達(dá)式是可選的,可以省略。如果表達(dá)式省略,switch 語句可以看成是 switch true,將會(huì)對(duì) case 語句進(jìn)行條件判斷,如果判斷為 true 將會(huì)執(zhí)行相應(yīng) case 的代碼塊。
package?main
import?(
????"fmt"
)
func?main()?{
????num?:=?75
????switch?{?//?expression?is?omitted
????case?num?>=?0?&&?num?<=?50:
????????fmt.Printf("%d?is?greater?than?0?and?less?than?50",?num)
????case?num?>=?51?&&?num?<=?100:
????????fmt.Printf("%d?is?greater?than?51?and?less?than?100",?num)
????case?num?>=?101:
????????fmt.Printf("%d?is?greater?than?100",?num)
????}
}
執(zhí)行[5]
上面的代碼中,switch 中沒有表達(dá)式,因此它被認(rèn)為是 true,將會(huì)對(duì) case 語句進(jìn)行判斷,判斷 case num >= 51 && num <= 100 為 true,所以輸出:
75?is?greater?than?51?and?less?than?100
這種類型的 switch 被認(rèn)為是多個(gè) if-else 子句的替代方案。
fallthrough 語句
Go 語言里,執(zhí)行完 case 語句的代碼塊將會(huì)立即跳出 switch 語句。使用 fallthrough 語句,可以在執(zhí)行完該 case 語句后,不跳出,繼續(xù)執(zhí)行下一個(gè) case 語句。
我們來寫一個(gè)示例來好好理解下 fallthrough 語句。該示例將檢查輸入的數(shù)字是否小于 50、100 或 200。例如,如果我們輸入 75,程序?qū)⒋蛴?75 小于 100 和 200。我們將使用 fallthrough 來實(shí)現(xiàn)這一點(diǎn)。
package?main
import?(
????"fmt"
)
func?number()?int?{
????????num?:=?15?*?5
????????return?num
}
func?main()?{
????switch?num?:=?number();?{?//num?is?not?a?constant
????case?num?50:
????????fmt.Printf("%d?is?lesser?than?50\n",?num)
????????fallthrough
????case?num?100:
????????fmt.Printf("%d?is?lesser?than?100\n",?num)
????????fallthrough
????case?num?200:
????????fmt.Printf("%d?is?lesser?than?200",?num)
????}
}
執(zhí)行[6]
switch 和 case 語句不只是常量,也可以在程序運(yùn)行時(shí)計(jì)算得到。上面代碼的第 14 行,num 使用 number() 函數(shù)的返回值初始化,第 18 行的 case 語句 case num < 100: 判斷為 true,所以輸出 75 is lesser than 100。執(zhí)行完 case 語句,下一行代碼是 fallthrough 語句,此時(shí)程序不會(huì)跳出,而是繼續(xù)執(zhí)行下一條 case,打印 75 is lesser than 200,所以程序輸出:
75?is?lesser?than?100
75?is?lesser?than?200
fallthrough 語句必須是 case 語句塊中最后一行代碼,如果出現(xiàn)在 case 語句中間,編譯時(shí)將會(huì)報(bào)錯(cuò):fallthrough statement out of place。
即使 fallthrough 后面的 case 語句判定為 false,也會(huì)繼續(xù)執(zhí)行
使用 fallthrough 時(shí)需要注意一點(diǎn),即使后面的 case 語句判定為 false,也會(huì)繼續(xù)執(zhí)行。
請(qǐng)看下面的代碼:
package?main
import?(
????"fmt"
)
func?main()?{
????switch?num?:=?25;?{
????case?num?50:
????????fmt.Printf("%d?is?lesser?than?50\n",?num)
????????fallthrough
????case?num?>?100:
????????fmt.Printf("%d?is?greater?than?100\n",?num)
????}
}
執(zhí)行[7]
上面的代碼中,num 等于 25,小于 50,所以第 9 行的 case 判斷為 true,執(zhí)行該語句。這個(gè) case 語句最后一行是 fallthrough,繼續(xù)執(zhí)行下一個(gè) case,不滿足條件 case num > 100,判斷為 false,但是 fallthrough 會(huì)忽視這點(diǎn),即使結(jié)果是 false,也會(huì)繼續(xù)執(zhí)行該 case 塊。
所以程序輸出:
25?is?lesser?than?50
25?is?greater?than?100
因此,請(qǐng)確保使用 fallthrough 語句時(shí)程序?qū)?huì)發(fā)生什么。
還有一點(diǎn)需要注意,fallthrough 不能用在最后一個(gè) case 語句中,否則編譯將會(huì)報(bào)錯(cuò):
cannot?fallthrough?final?case?in?switch
break
break 可以用來提前結(jié)束 switch 語句。我們通過一個(gè)示例來了解下工作原理:
我們添加一個(gè)條件,如果 num 小于 0,則 switch 提前結(jié)束。
package?main
import?(
????"fmt"
)
func?main()?{
????switch?num?:=?-5;?{
????case?num?50:
????????if?num?0?{
????????????break
????????}
????????fmt.Printf("%d?is?lesser?than?50\n",?num)
????????fallthrough
????case?num?100:
????????fmt.Printf("%d?is?lesser?than?100\n",?num)
????????fallthrough
????case?num?200:
????????fmt.Printf("%d?is?lesser?than?200",?num)
????}
}
執(zhí)行[8]
上面的代碼,num 初始化為 -5,當(dāng)程序執(zhí)行到第 10 行代碼的 if 語句時(shí),滿足條件 num < 0,執(zhí)行 break,提前結(jié)束 switch,所以程序不會(huì)有任何輸出。
跳出外部 for 循環(huán)
當(dāng) for 循環(huán)中包含 switch 語句時(shí),有時(shí)可能需要提前終止 for 循環(huán)。這可以通過給 for 循環(huán)打個(gè)標(biāo)簽,并且在 switch 語句中通過 break 跳轉(zhuǎn)到該標(biāo)簽來實(shí)現(xiàn)。我們來看個(gè)例子,實(shí)現(xiàn)隨機(jī)生成一個(gè)偶數(shù)的功能。
我們將創(chuàng)建一個(gè)無限 for 循環(huán),并且使用 switch 語句判斷隨機(jī)生成的數(shù)字是否為偶數(shù),如果是偶數(shù),則打印該數(shù)字并且使用標(biāo)簽的方式終止 for 循環(huán)。rand 包的 Intn() 函數(shù)用于生成非負(fù)偽隨機(jī)數(shù)。
package?main
import?(
????"fmt"
????"math/rand"
)
func?main()?{
randloop:
????for?{
????????switch?i?:=?rand.Intn(100);?{
????????case?i%2?==?0:
????????????fmt.Printf("Generated?even?number?%d",?i)
????????????break?randloop
????????}
????}
}
執(zhí)行[9]
上面代碼的第 9 行,給 for 循環(huán)打了個(gè)標(biāo)簽 randloop。Intn() 函數(shù)會(huì)生成 0-99 的隨機(jī)數(shù),當(dāng)為偶數(shù)時(shí),第 14 行代碼會(huì)被執(zhí)行,跳轉(zhuǎn)到標(biāo)簽 randloop 結(jié)束 for 循環(huán)。
程序輸出(因?yàn)槭请S機(jī)數(shù),你的執(zhí)行結(jié)果可能與下面的不通):
Generated?even?number?18
需要注意的是,如果使用不帶標(biāo)簽的 break 語句,則只會(huì)中斷 switch 語句,for 循環(huán)將繼續(xù)運(yùn)行,所以給 for 循環(huán)打標(biāo)簽,并在 switch 內(nèi)的 break 語句中使用該標(biāo)簽才能終止 for 循環(huán)。
switch 語句還可以用于類型判斷,我們將在學(xué)習(xí) interface 時(shí)再來研究這點(diǎn)。
via: https://golangbot.com/switch/
作者:Naveen R
參考資料
執(zhí)行: https://play.golang.org/p/94ktmJWlUom
[2]執(zhí)行: https://play.golang.org/p/7qrmR0hdvHH
[3]執(zhí)行: https://play.golang.org/p/Fq7U7SkHe1
[4]執(zhí)行: https://play.golang.org/p/AAVSQK76Me7
[5]執(zhí)行: https://play.golang.org/p/KPkwK0VdXII
[6]執(zhí)行: https://play.golang.org/p/svGJAiswQj
[7]執(zhí)行: https://play.golang.org/p/sjynQMXtnmY
[8]執(zhí)行: https://play.golang.org/p/UHwBXPYLv1B
[9]執(zhí)行: https://play.golang.org/p/0bLYOgs2TUk
資料下載
點(diǎn)擊下方卡片關(guān)注公眾號(hào),發(fā)送特定關(guān)鍵字獲取對(duì)應(yīng)精品資料!
回復(fù)「電子書」,獲取入門、進(jìn)階 Go 語言必看書籍。
回復(fù)「視頻」,獲取價(jià)值 5000 大洋的視頻資料,內(nèi)含實(shí)戰(zhàn)項(xiàng)目(不外傳)!
回復(fù)「路線」,獲取最新版 Go 知識(shí)圖譜及學(xué)習(xí)、成長路線圖。
回復(fù)「面試題」,獲取四哥精編的 Go 語言面試題,含解析。
回復(fù)「后臺(tái)」,獲取后臺(tái)開發(fā)必看 10 本書籍。
對(duì)了,看完文章,記得點(diǎn)擊下方的卡片。關(guān)注我哦~???????
-------------------?End?-------------------
往期精彩文章推薦:

歡迎大家點(diǎn)贊,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持
想加入學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群】
萬水千山總是情,點(diǎn)個(gè)【在看】行不行
