Flowcontrol

判断与循环

分支语句 if

Go 中 if 语句没有 ( ),但是必须要有 { },使用上和其他语言没有差别,如下:

方式一:只有 if 语句

score := 60
if score >= 60 {
    fmt.Println("恭喜:及格了")
}
// output:恭喜:及格了

还可以有 else 语句代码段,如下:

score := 59
if score >= 60 {
    fmt.Println("恭喜:及格了")
} else {
    fmt.Println("很遗憾:未通过考核")
}
// output:很遗憾:未通过考核

方式二:Go 中特有便捷语句写法,比如使用 strconv 包中 Atoi 函数,将一个字符串的数值 15 转为整数:

if i, e := strconv.Atoi("15"); e == nil{
    fmt.Println(i)  // 15
}
fmt.Print(i) // undefined: i

此函数转换后有两个返回值 func Atoi(s string) (int, error),一个是 int 类型数值,一个是 error 错误消息,

如果将转换后的结果,放在 if 语句内,后面还可以进行对变量 e 进行条件判断,但是变量 i 和 e 的作用域只能在 if 语句内。

接下来我们稍微玩点高级的,利用 Go 中的 os 包,通过接收参数 score 值,完成分数的判断输出,如下示例:

点击预览完整示例
// gobing.io/ch5/if.go
package main

import (
  "fmt"
  "os"
  "strconv"
)

func main() {
  args := os.Args
  // 至少得有一个参数
  if len(args) < 1 || args == nil {
      return
  }
  // 转为数值类型
  score, e := strconv.Atoi(args[1])
  if e != nil {
      fmt.Println(e)
      return
  }
  if score > 100 || score < 0 {
      fmt.Println("输入分值有误")
      return
  }
  if score >= 60 {
      fmt.Println("恭喜:及格了")
  }
  if score < 60 {
      fmt.Println("很遗憾:未通过考核")
  }
}

// 测试结果:
// ➜  go run if.go 15
// 很遗憾:未通过考核
// ➜  go run if.go 60
// 恭喜:及格了
// ➜  go run if.go -1
// 输入分值有误
// ➜  go run if.go 1000
// 输入分值有误

分支语句 switch

因为 if 分支语句只能是 bool 类型,对于其他类型的流程控制,switch 就派上用场了。

写法一:有 switch 条件

var grade string = "A"
switch grade {
case "A":
    fmt.Println("优秀")
case "B":
    fmt.Println("良好")
case "C":
    fmt.Println("及格")
default:
    fmt.Println("很尴尬,不及格")
}
// output:优秀

写法二:没有条件的 switch 时,同 switch true 一样。

t := time.Now()
switch {
case t.Hour() < 12:
    fmt.Println("Good morning!")
case t.Hour() < 17:
    fmt.Println("Good afternoon.")
default:
    fmt.Println("Good evening.")
}
// output:Good afternoon.

小结:

  • 每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止
  • Go 中 case 匹配项后面也不需要再加 break,自带 break 语句
  • 匹配后不再继续执行后面的 case 语句,如果需要执行可以使用关键词 fallthrough

一个 fallthrough 示例:

m := 2
switch m {
case 1:
    fmt.Println("case 1")
case 2:
    fmt.Println("case 2")
    fallthrough
case 3:
    fmt.Println("case 3")
}
// output:
// case 2
// case 3

解释:fallthrough 无条件的继续执行匹配下面所有 case 代码片段(拥有强大穿透力)

循环语句 for

Go 只有一种循环结构——for 循环,for 循环没有 ( ) 同样必须要有 { },使用上和其他语言没有差别,

比如:求 1 到 10(包含)数之和:

sum := 0
for i := 0; i <= 10; i++ {
    sum += i
}
fmt.Println(sum) // 55

可以省略到前置和后置语句,像这样:

total := 1
for ; total < 3; {
    fmt.Println("loop:", total)
    total += total
}
fmt.Println("end:",total)
// output:
// loop: 1
// loop: 2
// end: 4

Go 中没有 while 语句,因为 Go 中的 for 就可以实现 while ,比如继续简化上面的写法(省掉前后的 ; 号),如下:

total := 1
for total < 3 {
    fmt.Println("loop:", total)
    total += total
}
fmt.Println("end:", total)
// output:
// loop: 1
// loop: 2
// end: 4

是不是有很强的赶脚,在 Go 实现一个死循环,那就更简单了,把条件去掉就可以了,如下:

for {
    fmt.Println("loop")
}

循环中 continue

  • continue 跳过当前循环条件,进入下一个条件继续循环

示例:

for i := 0; i < 5; i++ {
    if i == 3 {
        continue
    }
    fmt.Println(i)
}
// output:
// 0
// 1
// 2
// 4

循环中 break

  • break 终止循环语句,结束循环

示例:

    for i := 0; i < 5; i++ {
        if i == 3 {
            break
        }
        fmt.Println(i)
    }
// output:
// 0
// 1
// 2