鍍金池/ 教程/ GO/ 5.3 switch 結(jié)構(gòu)
4.7 strings 和 strconv 包
13.6 啟動(dòng)外部命令和程序
?# 11.4 類型判斷:type-switch
12.1 讀取用戶的輸入
10.6 方法
12.2 文件讀寫
13 錯(cuò)誤處理與測試
9.3 鎖和 sync 包
12.3 文件拷貝
?# 11.7 第一個(gè)例子:使用 Sorter 接口排序
?# 11.5 測試一個(gè)值是否實(shí)現(xiàn)了某個(gè)接口
6.4 defer 和追蹤
12.10 XML 數(shù)據(jù)格式
13.10 性能調(diào)試:分析并優(yōu)化 Go 程序
?# 11.1 接口是什么
2.2 Go 環(huán)境變量
2.6 安裝目錄清單
2.5 在 Windows 上安裝 Go
11.11 Printf 和反射
1.2 語言的主要特性與發(fā)展的環(huán)境和影響因素
9.0 包(package)
7.4 切片重組(reslice)
13.2 運(yùn)行時(shí)異常和 panic
10.2 使用工廠方法創(chuàng)建結(jié)構(gòu)體實(shí)例
12.8 使用接口的實(shí)際例子:fmt.Fprintf
2.4 在 Mac OS X 上安裝 Go
3.8 Go 性能說明
7.2 切片
8.0 Map
3.1 Go 開發(fā)環(huán)境的基本要求
5.6 標(biāo)簽與 goto
6.10 使用閉包調(diào)試
9.5 自定義包和可見性
4.3 常量
?# 11.2 接口嵌套接口
6.5 內(nèi)置函數(shù)
前言
10.8 垃圾回收和 SetFinalizer
2.8 Go 解釋器
13.7 Go 中的單元測試和基準(zhǔn)測試
6.8 閉包
4.9 指針
13.1 錯(cuò)誤處理
10.1 結(jié)構(gòu)體定義
5.1 if-else 結(jié)構(gòu)
6.6 遞歸函數(shù)
9.9 通過 Git 打包和安裝
2.7 Go 運(yùn)行時(shí)(runtime)
10.7 類型的 String() 方法和格式化描述符
3.7 其它工具
9.6 為自定義包使用 godoc
11.12 接口與動(dòng)態(tài)類型
13.3 從 panic 中恢復(fù)(Recover)
10.3 使用自定義包中的結(jié)構(gòu)體
11.14 結(jié)構(gòu)體、集合和高階函數(shù)
3.6 生成代碼文檔
9.2 regexp 包
4.1 文件名、關(guān)鍵字與標(biāo)識(shí)符
?# 11.6 使用方法集與接口
7.0 數(shù)組與切片
7.1 聲明和初始化
12.11 用 Gob 傳輸數(shù)據(jù)
5.5 Break 與 continue
1.1 起源與發(fā)展
?# 11 接口(Interfaces)與反射(reflection)
6.9 應(yīng)用閉包:將函數(shù)作為返回值
4.2 Go 程序的基本結(jié)構(gòu)和要素
8.6 將 map 的鍵值對(duì)調(diào)
6.11 計(jì)算函數(shù)執(zhí)行時(shí)間
5.0 控制結(jié)構(gòu)
10.5 匿名字段和內(nèi)嵌結(jié)構(gòu)體
4.6 字符串
3.0 編輯器、集成開發(fā)環(huán)境與其它工具
13.8 測試的具體例子
7.6 字符串、數(shù)組和切片的應(yīng)用
8.4 map 類型的切片
3.9 與其它語言進(jìn)行交互
7.3 For-range 結(jié)構(gòu)
9.7 使用 go install 安裝自定義包
6.0 函數(shù)
9.8 自定義包的目錄結(jié)構(gòu)、go install 和 go test
6.3 傳遞變長參數(shù)
13.9 用(測試數(shù)據(jù))表驅(qū)動(dòng)測試
11.9 空接口
8.1 聲明、初始化和 make
6.2 函數(shù)參數(shù)與返回值
9.11 在 Go 程序中使用外部庫
3.3 調(diào)試器
4.5 基本類型和運(yùn)算符
?# 11.8 第二個(gè)例子:讀和寫
12.5 用 buffer 讀取文件
總結(jié):Go 中的面向?qū)ο?/span>
11.10 反射包
12.7 用 defer 關(guān)閉文件
9.4 精密計(jì)算和 big 包
4.4 變量
6.1 介紹
13.4 自定義包中的錯(cuò)誤處理和 panicking
12.4 從命令行讀取參數(shù)
9.10 Go 的外部包和項(xiàng)目
8.3 for-range 的配套用法
3.5 格式化代碼
10.4 帶標(biāo)簽的結(jié)構(gòu)體
7.5 切片的復(fù)制與追加
?# 11.3 類型斷言:如何檢測和轉(zhuǎn)換接口變量的類型
5.4 for 結(jié)構(gòu)
4.8 時(shí)間和日期
2.3 在 Linux 上安裝 Go
12 讀寫數(shù)據(jù)
6.12 通過內(nèi)存緩存來提升性能
9.1 標(biāo)準(zhǔn)庫概述
12.6 用切片讀寫文件
10 結(jié)構(gòu)(struct)與方法(method)
8.5 map 的排序
12.9 JSON 數(shù)據(jù)格式
13.5 一種用閉包處理錯(cuò)誤的模式
3.2 編輯器和集成開發(fā)環(huán)境
12.12 Go 中的密碼學(xué)
5.2 測試多返回值函數(shù)的錯(cuò)誤
6.7 將函數(shù)作為參數(shù)
8.2 測試鍵值對(duì)是否存在及刪除元素
3.4 構(gòu)建并運(yùn)行 Go 程序
2.1 平臺(tái)與架構(gòu)
5.3 switch 結(jié)構(gòu)

5.3 switch 結(jié)構(gòu)

相比較 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é)的名稱(不用考慮月份的日期)。

鏈接