Golang 多路條件語句 Switch 語法詳解

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/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佛吓,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子垂攘,更是在濱河造成了極大的恐慌维雇,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晒他,死亡現(xiàn)場離奇詭異吱型,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)陨仅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門津滞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人灼伤,你說我怎么就攤上這事触徐。” “怎么了狐赡?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵撞鹉,是天一觀的道長。 經(jīng)常有香客問我颖侄,道長鸟雏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任览祖,我火速辦了婚禮崔慧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘穴墅。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布玄货。 她就那樣靜靜地躺著皇钞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪松捉。 梳的紋絲不亂的頭發(fā)上夹界,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機(jī)與錄音隘世,去河邊找鬼可柿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛丙者,可吹牛的內(nèi)容都是我干的复斥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼械媒,長吁一口氣:“原來是場噩夢啊……” “哼目锭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纷捞,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤痢虹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后主儡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奖唯,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年糜值,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丰捷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡臀玄,死狀恐怖瓢阴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情健无,我是刑警寧澤荣恐,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站累贤,受9級特大地震影響叠穆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜臼膏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一硼被、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧渗磅,春花似錦嚷硫、人聲如沸检访。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脆贵。三九已至,卻和暖如春起暮,著一層夾襖步出監(jiān)牢的瞬間卖氨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工负懦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留筒捺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓纸厉,卻偏偏與公主長得像系吭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子残腌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348