if ... else、switch 条件式


在分支判断的控制上,Go 提供了if...elseswitch语法,相较于其他提供类似语法的语言,在 Go 中if...elseswitch语法的相似性更高。

if..else 语法

直接来看个if..else的实例:

package main

import "fmt"

func main() {
    input := 10
    remain := input % 2
    if remain == 1 {
        fmt.Printf("%d 为奇数\n", input)
    } else {
        fmt.Printf("%d 为偶数\n", input)
    }
}

在 Go 中,if之后直接写判断式可以不用使用()括号,而{}是必要的,这样应该是比较能避免Apple 曾经发生某个函数中有两个连续缩排而引发的问题

...       
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
        goto fail;
        goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
        goto fail;
...

Go 的if可以使用:=定义与指定变量值,与判断式之间以分号区隔,因此方才的范例也可以写成:

package main

import "fmt"

func main() {
    input := 10
    if remain := input % 2; remain == 1 {
        fmt.Printf("%d 为奇数\n", input)
    } else {
        fmt.Printf("%d 为偶数\n", input)
    }
}

这么一来,remain变量就只在if..else的区块中有作用。如果要使用:=定义与指定多个变量值,可以写成if var1, var2 := 10, 20; cond的形式。if...else可以组成if...else if...else形式,例如:

package main

import "fmt"

func main() {
    var level rune
    if score := 88; score >= 90 {
        level = 'A'
    } else if score >= 80 && score < 90 {
        level = 'B'
    } else if score >= 70 && score < 80 {
        level = 'C'
    } else if score >= 60 && score < 70 {
        level = 'D'
    } else {
        level = 'E'
    }
    fmt.Printf("得分等级:%c\n", level)
}

switch 语法

实际上,对于上头的范例,可以改用switch来编写,程序会更为简洁:

package main

import "fmt"

func main() {
    var level rune
    score := 88

    switch score / 10 {
    case 10, 9:
        level = 'A'
    case 8:

        level = 'B'
    case 7:
        level = 'C'
    case 6:
        level = 'D'
    default:
        level = 'E'
    }
    fmt.Printf("得分等级:%c\n", level)
}

注意,与 C/C++ 或 Java 等语言不同的是,Go 的switch比对成功后,不会自动往下执行,因而不用编写break,有多个条件想符合时,在同一case中使用逗号区隔。如果真的想在比对成功后,往下一个case中的陈述执行,可以使用fallthrough,例如:

package main

import "fmt"

func main() {
    var level rune

    switch score := 100; score / 10 {
    case 10:
        fmt.Println("满分喔!")
        fallthrough
    case 9:
        level = 'A'
    case 8:

        level = 'B'
    case 7:
        level = 'C'
    case 6:
        level = 'D'
    default:
        level = 'E'
    }
    fmt.Printf("得分等级:%c\n", level)
}

在上面的例子中,如果没有fallthrough,那么只会显示 “满分喔!“,而不会执行case 9中的level = 'A',因此最后显示得分等级时,不会有 A 的字眼。在上头也可以看到,switch中也可以使用:=定义与初始化变量。

实际上,Go 的switch中,case不用是常数,只要switch的值类型与case比对的类型符合,也可以是个变量或表达式,甚至还可以接受布尔表达式,例如:

package main

import "fmt"

func main() {
    var level rune
    score := 88
    switch {
    case score >= 90:
        level = 'A'
    case score >= 80 && score < 90:
        level = 'B'
    case score >= 70 && score < 80:
        level = 'C'
    case score >= 60 && score < 70:
        level = 'D'
    default:
        level = 'E'
    }
    fmt.Printf("得分等级:%c\n", level)
}

在上面的例子中,switch没有指定任何变量,此时等同于switch true,这时的case可以接受布尔表达式,可用来取代if...else if...else的风格。


展开阅读全文