> For the complete documentation index, see [llms.txt](https://sunwenfei.gitbook.io/sunwenfei/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sunwenfei.gitbook.io/sunwenfei/golang/golang-ji-chu-jiao-cheng/tiao-jian-xun-huan/switch-yu-ju.md).

# switch语句

`switch`语句是条件语句的一种。`switch`语句先计算一个表达式的值，然后将计算出来的值跟一列可能值进行比较，匹配到哪种情况就执行哪个代码块。`switch`语句可以等价于多个`if else`语句。

也许举个例子更加容易理解，下面我们写一个程序，根据数字输出对应的手指名称。比如1表示大拇指，2表示食指。

```go
package main

import "fmt"

func main() {  
    finger := 4
    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")

    }
}
```

[Go Playground在线运行](https://play.golang.org/p/afW0YmM3yXF) 该程序中`switch finger`语句将`finger`的值跟每一个`case`值从前到后依次去比较，匹配上会执行对应的代码块。由于`switch finger`语句执行时`finger`值为4，因此`case 4`对应的代码块得以执行，打印出`Ring`。

`switch`语句中`case`值不允许重复，例如下面的程序有两个`case`值均为4，会报错：

```go
package main

import "fmt"

func main() {  
    finger := 4
    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")

    }
}
```

[Go Playground在线运行](https://play.golang.org/p/ibBwPF60t9Q)

#### 兜底case

前面程序中用手指做例子来说明`switch`语句用法。我们一只手上只有5个手指，因此可以匹配到数字1到5。那如果前面给`finger`赋值为其他错误的值，比如6，怎么办？这时兜底case就派上用场了。

```go
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")
    }
}
```

[Go Playground在线运行](https://play.golang.org/p/Q4CYU9j4bZX) 这里由于`finger`值为8，无法匹配到任何一个`case`值，因此会执行兜底case的代码块，打印出`incorrect finger number`。

细心的话你会注意到，我们将`finger`的初始化置于了`switch`语句内。这点跟`if else`语句类似，均支持这种用法。这种方式初始化`finger`值，`finger`仅在`switch`语句内部可见。

#### case合并

如果要执行的代码块相同，我们可以将多个case合并成一条语句。比如下面判断元音字母的程序：

```go
package main

import "fmt"

func main() {  
    letter := "i"
    switch letter {
    case "a", "e", "i", "o", "u": //multiple expressions in case
        fmt.Println("vowel")
    default:
        fmt.Println("not a vowel")
    }
}
```

[Go Playground在线运行](https://play.golang.org/p/R5_TncSPs1A) 该程序判断`letter`变量是否是元音字母，`case "a", "e", "i", "o", "u"`语句将多种情况(所有元音字母)合并成了一条`case`语句。

#### `switch true`

如果要执行的`switch`语句为`switch true`，则可简写将表达式`true`省去。注意这时`case`值都是跟`true`比较。

```go
package main

import "fmt"

func main() {  
    num := 75
    switch { // expression is omitted
    case num >= 0 && num <= 50:
        fmt.Println("num is greater than 0 and less than 50")
    case num >= 51 && num <= 100:
        fmt.Println("num is greater than 51 and less than 100")
    case num >= 101:
        fmt.Println("num is greater than 100")
    }
}
```

[Go Playground在线运行](https://play.golang.org/p/BCQMYYMr3QJ) 该程序中`num`值为75，`case num >= 51 && num <= 100`判断通过，因此打印`num is greater than 51 and less than 100`。其实我们简单思考下就应该知道，这种用法完全可用`if else`语句替换。

#### fallthrough

细心的话就会发现，Golang中的`case`语句跟`JavaScript`等其他编程语言不同，不需要`break`语句即可在执行完匹配上的代码块后立即退出整个`switch`语句。那么如果希望继续判断并匹配后序的`case`语句怎么实现呢？也有办法，就是用`fallthrough`。

```go
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)
    }
}
```

[Go Playground在线运行](https://play.golang.org/p/rViLL17s6Ze) 该程序中`num`值为75，因此`case num < 100`判断通过，执行对应的代码块，由于使用了`falltrough`，因此执行流程向后贯穿，接着去匹配其他的`case`。由于`case num < 200`也判断通过，因此也执行对应的代码块。该程序输出如下：

```
75 is lesser than 100
75 is lesser than 200
```

有过其他编程语言经验的人都应该知道，我们大部分情况下都会使用`switch`语句的`break`来退出`switch`语句，因此Golang的设计更加优雅。从这一点上也不得不说，Golang确实是取其精华，去其糟粕。

需要注意`fallthrough`必须在`case`代码块的最后执行，否则会报错。

另外还有一个`type switch`语句，我们后面介绍接口时再讨论。
