Go 入门指南笔记 - 控制结构 - 1

if-else 结构

// 1. 最基础的写法
if condition1 {
    // do something
} else if condition2 {
    // do something else
}else {
    // catch-all or default
}
// 2. 测试变量的值
bool1 := true
if bool1 {
    fmt.Printf("The value is true\n")
} else {
    fmt.Printf("The value is false\n")
}
// 3. 当 if 结构内有 break、continue、goto 或者 return 语句时,Go 代码的常见写法是省略 else 部分
if condition {
    return x
}
return y
// 4. 判断运行 Go 程序的操作系统类型,这可以通过常量 runtime.GOOS 来判断
// 这段代码一般被放在 init() 函数中执行。这儿还有一段示例来演示如何根据操作系统来决定输入结束的提示
var prompt = "Enter a digit, e.g. 3 "+ "or %s to quit."

func init() {
    if runtime.GOOS == "windows" {
        prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter")
    } else { //Unix-like
        prompt = fmt.Sprintf(prompt, "Ctrl+D")
    }
}
// 函数 Abs() 用于返回一个整型数字的绝对值:
func isGreater(x, y int) bool {
    if x > y {
        return true
    }
    return false
}
// isGreater 用于比较两个整型数字的大小
func isGreater(x, y int) bool {
    if x > y {
        return true
    }
    return false
}
// 5. if 可以包含一个初始化语句(如:给一个变量赋值)。这种写法具有固定的格式(在初始化语句后方必须加上分号)
if initialization; condition {
    // do something
}
val := 10
if val > max {
    // do something
}
// 使用简短方式 := 声明的变量的作用域只存在于 if 结构中
// 如果变量在 if 结构之前就已经存在,那么在 if 结构中,该变量原来的值会被隐藏。
if val := 10; val > max {
    // do something
}

// 最复杂的语句用法,在初始化语句中获取函数 process() 的返回值
if value := process(data); value > max {
    return true;
}

测试多返回值函数的错误

Go 语言的函数经常使用两个返回值来表示执行是否成功:

  • 返回某个值以及 true 表示成功
  • 返回零值(或 nil)和 false 表示失败
  • 当不使用 true 或 false 的时候,也可以使用一个 error 类型的变量来代替作为第二个返回值
    • 成功执行的话,error 的值为 nil,
    • 否则就会包含相应的错误信息(Go 语言中的错误类型为 error: var err error

很明显需要用一个 if 语句来测试执行结果;由于其符号的原因,这样的形式又称之为 comma,ok 模式。

程序应该在最接近的位置检查所有相关的错误,至少需要暗示用户有错误发生并对函数进行返回,甚至中断程序。

// 这是测试 err 变量是否包含一个真正的错误(if err != nil)的习惯用法。
value, err := pack1.Function1(param1)
if err != nil {
    return err;
}
// 未发生错误,继续执行:
// 如果我们想要在错误发生的同时终止程序的运行,我们可以使用 os 包的 Exit 函数
// 此处的退出代码 1 可以使用外部脚本获取到
if err != nil {
    fmt.Printf("Program stopping with error %v", err)
    os.Exit(1)
}
// 可以将错误的获取放置在 if 语句的初始化部分
if err := file.Chmod(0664); err !=nil {
    fmt.Println(err)
    return err
}
// 将 ok-pattern 的获取放置在 if 语句的初始化部分,然后进行判断:
if value, ok := readData(); ok {
    // ...
}
// as same as
value, ok := readData()
if ok {
    // ...
}
// 也可以进行一层忽略错误的封装
func atoi (s string) (n int) {
    n, _ = strconv.Atoi(s)
    return
}

switch 结构

Go 语言中的 switch 结构使用上更加灵活。它接受任意形式的表达式。

switch var1 {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}
  • 变量 var1 可以是任何类型,而 val1 和 val2 则可以是同类型的任意值。
  • 类型不被局限于常量或整数,但必须是相同的类型;或者最终结果为相同类型的表达式。
  • 可以同时测试多个可能符合条件的值,使用逗号分割它们,例如:case val1, val2, val3
  • 每一个 case 分支都是唯一的,从上直下逐一测试,直到匹配为止。
  • 一旦成功地匹配到每个分支,在执行完相应代码后就会退出整个 switch 代码块,也就是说您不需要特别使用 break 语句来表示结束。
  • 如果在执行完每个分支的代码后,还希望继续执行后续分支的代码,可以使用 fallthrough 关键字来达到目的。
  • case ...: 语句之后,您不需要使用花括号将多行语句括起来,但您可以在分支中进行任意形式的编码。
  • 当代码块只有一行时,可以直接放置在 case 语句之后。
  • 可以使用 return 语句来提前结束代码块的执行。
  • 当您在 switch 语句块中使用 return 语句,并且您的函数是有返回值的,您还需要在 switch 之后添加相应的 return 语句以确保函数始终会返回。
  • 可选的 default 分支可以出现在任何顺序,但最好将它放在最后。

switch 语句的第二种形式是不提供任何被判断的值(实际上默认为判断是否为 true),然后在每个 case 分支中进行测试不同的条件。当任一分支的测试结果为 true 时,该分支的代码会被执行。这看起来非常像链式的 if-else 语句,但是在测试条件非常多的情况下,提供了可读性更好的书写方式。

switch {
    case condition1:
        ...
    case condition2:
        ...
    default:
        ...
}
package main

import "fmt"

func main() {
    var num1 int = 7

    switch {
        case num1 < 0:
            fmt.Println("Number is negative")
        case num1 > 0 && num1 < 10:
            fmt.Println("Number is between 0 and 10")
        default:
            fmt.Println("Number is 10 or greater")
    }
}

switch 语句的第三种形式是包含一个初始化语句,这种形式可以非常优雅地进行条件判断。

switch initialization {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}
switch result := calculate(); {
    case result < 0:
        ...
    case result > 0:
        ...
    default:
        // 0
}

switch a, b := x[i], y[j]; {
    case a < b: t = -1
    case a == b: t = 0
    case a > b: t = 1
}

switch 语句还可以被用于 type-switch(详见第 11.4 节)来判断某个 interface 变量中实际存储的变量类型。

k := 6
switch k {
    case 4: fmt.Println("was <= 4"); fallthrough;
    case 5: fmt.Println("was <= 5"); fallthrough;
    case 6: fmt.Println("was <= 6"); fallthrough;
    case 7: fmt.Println("was <= 7"); fallthrough;
    case 8: fmt.Println("was <= 8"); fallthrough;
    default: fmt.Println("default case")
}

如果觉得我的文章对您有用,请在支付宝公益平台找个项目捐点钱。 @Victor Mar 8, 2019

奉献爱心