Golang 多路条件语句 Switch 语法详解

Switch 是 Go 语言中一种多路条件语句,一般搭配 case 语句使用。

执行逻辑

一个 switch case 条件结构如下所示:

switch simpleStatement; condition {
    case expression1,expression2:
        statements
    case expression3:
        statements
    default:
        statements
    }

和 if 语句类似,switch 语句也可以在条件语句之前执行一段简短的表达式(可以用于很方便的控制变量的作用域),switch case 开始执行时,会先执行这一个表达式(空也算一种),然后计算出条件语句的值,接着按从上到下,从左到右的顺序一个一个的执行 case 语句的条件表达式,如果值相等的话就会进入执行 case 条件下对应的语句。
如果所有的 case 条件都没有能匹配上的话,然后就会尝试执行 default 下对应的逻辑。

case 条件合并

如果有时候多个 case 条件对应的处理逻辑是一样的话,Go 语言中的 case 条件是可以合并的,多个条件用逗号分隔,判断顺序是从左到右。

func main()  {
    switch runtime.GOOS {
    case "linux","darwin" :
        println("unix环境")
    case "windows":
        println("windows环境")
    }
}

支持的类型

不像 Java 只支持整型进行判断(其他类型都是通过转化成整型实现的),Go 里的 switch 的参数是一个表达式,支持任何类型进行比较,甚至 switch 的条件还可以是一个空的,这个时候等价于 switch true,可以用于简化多个 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
    }
}

比如上方这个多重 if else 判断逻辑就可以用下方这个无参数的 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 语言中匹配到一个 case 条件执行完对应的逻辑之后就会跳出这个 switch 语句,等价于每个 case 处理逻辑之后都加了一个隐式的 break 语句。如果不想要隐式退出的话可以使用 fallthrough 语句来继续下一个 case 的处理逻辑。
隐式 break:

func main()  {
    switch runtime.GOOS {
    case "linux","darwin" :
        println("unix环境")
    case "windows":
        println("window环境")
    default:
        println("什么都不是")
    }
}

输出:

windows环境

强行 fallthrough:

func main()  {
    switch runtime.GOOS {
    case "linux","darwin" :
        println("unix环境")
        fallthrough
    case "windows":
        println("windows环境")
        fallthrough // 会继续执行下一个语句
    default:
        println("什么都不是")
    }
}

输出:

windows环境
什么都不是

不过这一点就和很多其他编程语言正好相反,比如:Java、C++。Java 和 C++ 中的 switch case 都是隐式 fallthrough,而break 则需要显示调用,这两种方式各有利弊吧,还是看不同的使用场景,不过 Java 12 中也加入了对于隐式 break 的支持。
另外 Go 语言中也是可以显示调用 break 提前跳出的,用法和循环语句中的 break 是一样的,也可以加标签指定跳出具体哪一段逻辑。
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

指定标签跳出 for 循环:

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 条件还可以是一种类型,这个特性在一个变量可能是多种类型时非常有用,虽然也可以 if else 加上类型断言来实现:

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,因为在申明变量时并没有指定具体类型,编译器会自行推导类型,而 int 是无类型整形的默认类型。)
同时 Type Switch 可以给赋值给一个变量,这个变量在不同的 case 中会变成对应 case 条件的类型(在合并了 case 语句之后会失效)

func main() {
    var i interface{}
    switch x := i.(type) {
    case error:
        x.Error()
    case fmt.Stringer:
        x.String()
    }
}

原文发表于:https://huweicai.com/go-switch/

你可能感兴趣的:(Golang 多路条件语句 Switch 语法详解)