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")
}