零基础 go - 23(流程控制 - switch)

0 阅读3分钟

在程序中,程序运行的流程控制决定程序是怎么样执行的。

一、主要三大流程控制

  • 顺序控制
  • 分支控制
  • 循环控制

二、switch 控制

switch...case 是一种多分支控制结构,可以根据不同的条件执行不同的代码块。go中的switch比其他语言更强大,可以实现多种分支控制

switch 语句用于基于不同条件执行不同动作,每个case分支都是唯一的,从上到下逐一测试,直到匹配为止

基本语法

image.png

流程图

image.png

switch 使用细节:

  • switch 执行流程是,先执行表达式得到值,然后和case比较,找到匹配的case后执行对应的代码块,执行完后不需要break,会自动跳出switch
  • switch 后面的表达式可以省略,表示对 true 进行判断;
  • switch后面可以是变量、常量、表达式、有返回值的函数等,甚至可以是一个空的switch,表示对true进行判断
  • switch 语句会从上到下逐一测试每个 case 分支,直到找到匹配的分支为止;
  • case 后的表达式也可以是一个范围或者一个类型;
  • case 的表达式可以有多个,使用 逗号 分隔
  • case 的字面量不能重复,否则会编译错误
  • case 中的匹配项不用加 break
  • 如果没有找到匹配的分支,会执行 default 分支(如果有的话)
  • case 后面的表达式的值的数据类型,必须和switch 的表达式数据类型保持一致
  • default 并不是必须的
  • switch 后面可以不跟表达式,类似于 if else 的效果
  • switch 后面也可以声明定义一个变量,分号结束(不推荐此类写法)
  • switch 的穿透 fallthrough ,如果在case语句后加这个fallthrough,则会继续执行下一个case
  • switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际的变量类型

代码示例

package main

import "fmt"

func main() {
    // switch 的常规使用
    var num int = 2
    switch num {
        case 1:
            fmt.Println("num=1")
        case 2:
            fmt.Println("num=2")
        default:
            fmt.Println("num is not 1 or 2")
    }


    // switch 后面可以是一个表达式
    var a int = 10
    var b int = 20
    switch a + b {
        case 30:
            fmt.Println("a+b=30")
        case 40:
            fmt.Println("a+b=40")
        default:
            fmt.Println("a+b is not 30 or 40")
    }

    // switch 后面可以省略,表示对 true 进行判断
    var score int = 85
    switch {
        case score >= 90:
            fmt.Println("优秀")
        case score >= 80:
            fmt.Println("良好")
        case score >= 60:
            fmt.Println("及格")
        default:
            fmt.Println("不及格")
    }




    // switch 的穿透 fallthrough
    var grade int = 80
    switch {
        case grade == 90:
            fmt.Println("优秀")
            fallthrough
        case grade == 80:
            fmt.Println("良好") // 会输出
            fallthrough
        case grade == 60:
            fmt.Println("及格") // 会输出
        default:
            fmt.Println("不及格")
    }



    // case 后面的表达式可以有多个,使用 逗号 分隔。default 可以缺省
    var day int = 6
    switch day {
        case 1, 2, 3, 4, 5:
            fmt.Println("工作日")
        case 6, 7:
            fmt.Println("周末")
    }




    // case 的非字面量可以重复
    var num2 int = 2
    var a int = 1
    switch num2 {
        case 1:
            fmt.Println("num2=1")
        case a: // 正确
            fmt.Println("num2=a")
    }


    // case 的字面量不能重复,否则会编译错误
    // var num2 int = 2
    // switch num2 {
    // case 1:
    // fmt.Println("num2=1")
    // case 1: // 报错,case 1 重复
    // fmt.Println("num2=1")





    // switch 表达式的类型必须和case 后的表达式类型一致,否则报错
    // var num3 int = 2
    // switch num3 {
    // case "2": // 报错,num3 是 int 类型,"2" 是 string 类型
    // fmt.Println("num3=2")
    // }


    // switch 后可以直接声明定义一个变量,分号结束(不推荐这种写法)
    switch num4 := 2; num4 {
        case 1:
            fmt.Println("num4=1")
        case 2:
            fmt.Println("num4=2")
        default:
            fmt.Println("num4 is not 1 or 2")
    }




    // type-switch 判断 interface 变量中实际的变量类型
    var x interface{} = 123
    switch v := x.(type) {
        case int:
            fmt.Printf("x is int, value=%d\n", v) // v 在 case 块内被赋值为 x 的具体类型(这里是 int),可以直接使用
        case string:
            fmt.Printf("x is string, value=%s\n", v)
        default:
            fmt.Printf("x is of unknown type\n")
    }

}