流程控制语句

for 循环语句

  1. package main
  2. import "fmt"
  3. func main() {
  4. sum := 0
  5. // 如果条件表达式的值变为 false,那么迭代将终止。
  6. for i := 0; i < 10; i++ {
  7. sum += i
  8. }
  9. fmt.Println(sum)
  10. // 循环初始化语句和后置语句都是可选的。
  11. // for 是 Go 的 “while”
  12. // 基于此可以省略分号:C 的 while 在 Go 中叫做 for 。
  13. // 如果省略了循环条件,循环就不会结束,因此可以用更简洁地形式表达死循环。
  14. sum2 := 1
  15. for ; sum2 < 1000; {
  16. sum2 += sum2
  17. }
  18. fmt.Println(sum2)
  19. }

基本的 for 循环包含三个由分号分开的组成部分:

  • 初始化语句:在第一次循环执行前被执行
  • 循环条件表达式:每轮迭代开始前被求值
  • 后置语句:每轮迭代后被执行

if 语句

  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. func sqrt(x float64) string {
  7. if x < 0 {
  8. return sqrt(-x) + "i"
  9. }
  10. return fmt.Sprint(math.Sqrt(x))
  11. }
  12. func main() {
  13. fmt.Println(sqrt(2), sqrt(-4))
  14. }

就像 for 循环一样,Go 的 if 语句也不要求用 ( ) 将条件括起来,同时, { } 还是必须有的。

if 的便捷语句

  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. func pow(x, n, lim float64) float64 {
  7. if v := math.Pow(x, n); v < lim {
  8. return v
  9. }
  10. return lim
  11. }
  12. func main() {
  13. fmt.Println(
  14. pow(3, 2, 10),
  15. pow(3, 3, 20),
  16. )
  17. }

if 和 else 语句

  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. func pow(x, n, lim float64) float64 {
  7. if v := math.Pow(x, n); v < lim {
  8. return v
  9. } else {
  10. fmt.Printf("%g >= %g\n", v, lim)
  11. }
  12. // 这里开始就不能使用 v 了
  13. return lim
  14. }
  15. func main() {
  16. // 两个 pow 调用都在 main 调用 fmt.Println 前执行完毕了。
  17. fmt.Println(
  18. pow(3, 2, 10),
  19. pow(3, 3, 20),
  20. )
  21. }

在 if 的便捷语句定义的变量同样可以在任何对应的 else 块中使用。

switch 语句

  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. )
  6. func main() {
  7. fmt.Print("Go runs on ")
  8. switch os := runtime.GOOS; os {
  9. case "darwin":
  10. fmt.Println("OS X.")
  11. case "linux":
  12. fmt.Println("Linux.")
  13. default:
  14. // freebsd, openbsd,
  15. // plan9, windows...
  16. fmt.Printf("%s.", os)
  17. }
  18. }

在 if 的便捷语句定义的变量同样可以在任何对应的 else 块中使用。

switch 的执行顺序: 条件从上到下的执行,当匹配成功的时候停止。

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. fmt.Println("When's Saturday?")
  8. today := time.Now().Weekday()
  9. switch time.Saturday {
  10. case today + 0:
  11. fmt.Println("Today.")
  12. case today + 1:
  13. fmt.Println("Tomorrow.")
  14. case today + 2:
  15. fmt.Println("In two days.")
  16. default:
  17. fmt.Println("Too far away.")
  18. }
  19. }

没有条件的 switch 同 switch true 一样。

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. t := time.Now()
  8. switch {
  9. case t.Hour() < 12:
  10. fmt.Println("Good morning!")
  11. case t.Hour() < 17:
  12. fmt.Println("Good afternoon.")
  13. default:
  14. fmt.Println("Good evening.")
  15. }
  16. }

defer 语句

  1. package main
  2. import "fmt"
  3. func main() {
  4. // 2. 在输出 world
  5. defer fmt.Println("world")
  6. // 1. 先输出 hello
  7. fmt.Println("hello")
  8. }

defer 语句会延迟函数的执行直到上层函数返回。延迟调用的参数会立刻生成,但是在上层函数返回前函数都不会被调用。

defer 栈

延迟的函数调用被压入一个栈中。当函数返回时, 会按照后进先出的顺序调用被延迟的函数调用。

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("counting")
  5. for i := 0; i < 10; i++ {
  6. defer fmt.Println(i)
  7. }
  8. fmt.Println("done")
  9. }

可以运行demo defer 查看效果。