Go 语言流程控制

210 阅读2分钟

Go 语言提供的流程控制语句包括 ifswitchforgotoselect,其中 select 用于监听 channel(通道)在讲解通道的时候再详细介绍。

if 语句

语法:

if optionalStatement1; booleanExpression1 {
    block1
} else if optionalStatement2; booleanExpression2 {
    block2
} else {
    block3
}


其中 optionalStatement 是可选的表达式,真正决定分支走向的是 booleanExpression1 的值。

for 语句

Go 语言的 for 语句可以遍历数组,切片,映射等类型,也可以用于无限循环。以下是其语法:

for { // 无限循环
    block
}

for booleanExpression { // while循环,在Go语言中没有while关键字

}

for index, char := range aString { // 迭代字符串

}

for item := range aChannel { // 迭代通道

}

跳转语句

Go 语言中使用 goto 关键字实现跳转。goto 语句的语义非常简单,就是跳转到本函数内的某个标签,例如:


func myfunc(){
    i := 0
    THIS: //定义一个THIS标签
    fmt.Println(i)
    i++
    if i < 1 {
        goto THIS //跳转到THIS标签
    }
}

Go 语言中 switch 分支既可用于常用的分支就像 C 语言中的 switch一样,也可以用于类型开关,所谓类型开关就是用于判断变量属于什么类型。但是需要注意的是 Go 语言的 switch 语句不会自动贯穿,相反,如果想要贯穿需要添加 fallthrough 语句。表达式开关 switch 的语法如下:

switch optionalStatement; optionalExpression {
    case expression1: block1
    ...
    case expressionN: blockN
    default: blockD
}

下面是个例子:

switch {        // 没有表达式,默认为True值,匹配分支中值为True的分支
    case value < minimum:
        return minimum
    case value > maximum:
        return maximum
    default:
        return value
}

在上面的例子中,switch 后面没有默认的表达式,这个时候 Go 语言默认其值为 True。

在前面我们提到过类型断言,如果我们知道变量的类型就可以使用类型断言,但是当我们知道类型可能是许多类型中的一种时候,我们就可以使用类型开关。其语法如下:

switch optionalStatement; typeSwitchGuard {
    case type1: block1
    ...
    case typeN: blockN
    default: blockD
}

说了这么多,让我们进行下练习,创建源文件 switch_t.go,输入以下代码:

package main

import (
    "fmt"
)

func classchecker(items ...interface{}) { // 创建一个函数,该函数可以接受任意多的任意类型的参数
    for i, x := range items {
        switch x := x.(type) { // 创建了影子变量
        case bool:
            fmt.Printf("param #%d is a bool, value: %t\n", i, x)
        case float64:
            fmt.Printf("param #%d is a float64, value: %f\n", i, x)
        case int, int8, int16, int32, int64:
            fmt.Printf("param #%d is a int, value: %d\n", i, x)
        case uint, uint8, uint16, uint32, uint64:
            fmt.Printf("param #%d is a uint, value: %d\n", i, x)
        case nil:
            fmt.Printf("param #%d is a nil\n", i)
        case string:
            fmt.Printf("param #%d is a string, value: %s\n", i, x)
        default:
            fmt.Printf("param #%d's type is unknow\n", i)
        }
    }
}

func main() {
    classchecker(5, -17.98, "AIDEN", nil, true, complex(1, 1))

}

以上代码中我们首先创建了一个接收任意数量任意类型参数的函数,然后使用 for ... range aSlice 的语法迭代了每一个在切片 items中的元素,接着使用了 switch 类型开关判断了每一个参数的类型,并打印了其值和类型。程序运行输出如下:

$ go run switch_t.go
param #0 is a int, value: 5
param #1 is a float64, value: -17.980000
param #2 is a string, value: AIDEN
param #3 is a nil
param #4 is a bool, value: true
param #5's type is unknow