Go 编程 | 连载 09 - 条件和循环表达式

856 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

一、if 条件控制语句

if 表达式 {
    // 表达式为 true 时执行的代码块
} else if 表达式2 {
    // 表达式为 true 时执行的代码块
} else if 表达式3 {
    // 表达式为 true 时执行的代码块
} else {
    // 表达式为 true 时执行的代码块
}

需要注意的是 Go 中 if 控制语句的 { 不可以换行,必须要跟 if 关键字在同一行,否则会报错。

image.png

func main() {

   age := 3
   if age > 60 {
      fmt.Println("老年了")
   } else if age > 40 {
      fmt.Println("中年了")
   } else if age > 18 {
      fmt.Println("青年了")
   } else if age > 5 {
      fmt.Println("少年了")
   } else if age > 0 {
      fmt.Println("婴幼儿")
   } else {
      fmt.Println("输入错误")
   }

}

Go 中 if 语句支持在条件表达式中定义变量

func main() {
   // 变量定义在 if 条件表达式中
   if age := 3; age > 60 {
      fmt.Println("老年了")
   } else if age > 40 {
       // 其余代码不变
   }

}

在 if 条件表达式中定义的局部变量就只能在 if 代码块中使用。

二、switch 语句

switch 语句用于基于不同的条件执行不同的动作,if 条件语句的判断大多是范围的判断,如果条件表达式是一个具体的值,那么更适合使用 switch 语句来实现基于不同的值执行不同的操作

switch var {
    case val1:
        // 执行的操作
    case val2:
        // 执行的操作
    case val3:
        // 执行的操作
    default:
        // 默认执行的操作
}
func main() {

   seasonEnum := 2

   switch seasonEnum {
      case 1:
         fmt.Println("春天")
      case 2:
         fmt.Println("夏天")
      case 3:
         fmt.Println("秋天")
      case 4:
         fmt.Println("冬天")
      default:
         fmt.Println("输入错误")
   }
}

case 关键字后面也可以写多个值,多个值之间使用 , 隔开,当满足列出的任何一个值时都会往下执行

func main() {

   month := 4
   switch month {
   case 1, 3, 5, 7, 8, 10, 12:
      fmt.Println("这个月份有 31 天")
   case 4, 6, 9, 11:
      fmt.Println("这个月份有 30 天")
   case 2:
      fmt.Println("这个月有 28 天或者 29 天")
   default:
      fmt.Println("输入错误")
   }
}

执行上述代码,输出结果如下:

这个月份有 30 天

switch 语句也可以像 if 语句一样对表达式进行判断,然后根据判断结果选择要执行的分支

func main() {

   age := 10
   switch {
   case age > 60:
      fmt.Println("退休了")
   case age > 23:
      fmt.Println("工作了")
   default:
      fmt.Println("好好学习")
   }
}

执行上述代码,输出结果如下:

好好学习

case 关键字后不能定义变量。

三、for 循环

Go 语言中的 for 循环有 3 中形式。

for init; expr1; expr2 {}

for expr {}

// 类似 while 循环
for {}

其中 init 一般指赋值表达式,用于给控制变量初始化并赋值, expr1 和 expr2 都是条件表达式表示循环控制条件或者退出循环的条件。

for 循环的执行过程为:

  1. 先初始化并给控制变量赋值
  2. 判断控制变量是否满足 expr1 表达式1,若满足则执行循环体内的代码,然后在执行 expr2 表达式2;
  3. 接着进入第二次循环,再次判断控制变量是否满足 expr1 表达式1,如果不满足则退出循环。
func main() {

   // 计算 1-10累加和
   sum := 0
   i := 0
   for i = 1; i <= 10; i++ {
      sum += i
   }

   fmt.Println(i)
   fmt.Printf("1-10 的累计结果为:%v", sum)
}

执行上述代码,输出结果为:

11
1-10 的累计结果为:55

当 i 等于 10 时会继续执行 for 循环代码块内的代码,然后执行 ++ 操作变为 11,再次判断不满足条件所以退出循环,最终输出 i 的值为 11。

Go 中 for 循环的初始化控制变量表达式和条件判断表达式都可以省略

func main() {

   for {
      fmt.Println("Working")
   }
}

上述代码是一个死循环,会不断的打印 Working 字符串,非常类似 while 循环(Go 中没有 while 循环)。

for range 的用法

Go 中还有另一种循环既 for ... range 循环,该循环可以对 Go 中的切片 Slice、字典 Map、数组 Array 以及字符串进行遍历。

for idx, item := range data {}
func main() {

   team := "Avengers"

   for idx, item := range team {
      fmt.Println(idx, string(item))
   }

   members := []string{"stark", "hulk", "thor", "steve", "clint", "natasha"}

   for idx, mem := range members {
      fmt.Println(idx, mem)
   }

}

执行上述代码,输出结果如下:

0 A
1 v
2 e
3 n
4 g
5 e
6 r
7 s
0 stark
1 hulk
2 thor
3 steve
4 clint
5 natasha

使用 for ... range 遍历时需要两个变量来接收返回值,第一个返回值是元素所在的位置(索引),第二个返回值是元素的具体值,字符返回的是 ASCII 码。

Go 编程 | 连载 04 - 字符与字符串类型 中讲述字符串类型时提到对中英文混合的字符串求长度时要首先将字符串转成 rune 数组类型, 包含中文字符的字符串进行遍历时,也需要转成 rune 数组类型。

func main() {

   team := "Avengers 复仇者联盟"
   fmt.Println(len(team))

   for idx, item := range team {
      fmt.Println(idx, string(item))
   }

   team_arr := []rune(team)
   fmt.Println(len(team_arr))

   for idx, item := range team_arr {
      fmt.Println(idx, string(item))
   }

}

执行上述代码,输出结果如下:

24
0 A
1 v
2 e
3 n
4 g
5 e
6 r
7 s
8  
9 复
12 仇
15 者
18 联
21 盟
14
0 A
1 v
2 e
3 n
4 g
5 e
6 r
7 s
8  
9 复
10 仇
11 者
12 联
13 盟

break 和 continue 关键字

Go 中的 break 关键字和 continue 关键字的作用与其他语言中的作用一致,都是用于跳出循环,break 是跳出整个循环而 continue 是跳出当前循环。

func main() {

   members := []string{"stark", "hulk", "thor", "steve", "clint", "natasha"}

   fmt.Println("continue 关键字使用")
   for idx, mem := range members {
      if mem == "hulk" {
         fmt.Println("Strongest Avenger")
         continue
      }

      fmt.Println(idx, mem)
   }

   fmt.Println("break 关键字使用")
   for idx, mem := range members {
      if mem == "steve" {
         fmt.Println("First Avenger")
         break
      }

      fmt.Println(idx, mem)
   }

}

执行上述代码,输出结果如下:

continue 关键字使用
0 stark
Strongest Avenger
2 thor
3 steve
4 clint
5 natasha
break 关键字使用
0 stark
1 hulk
2 thor
First Avenger

四、goto 语句

Go 语言的 goto 语句可以无条件的转移到任意指定代码行执行;goto 语句通常会与条件语句配合使用,可以实现条件转移、构成循环体或者跳出循环体等功能。

goto label;
···
label: statement
func main() {

   i := 1

TANGO:
   for i < 5 {
      if i == 3 {
         i += 1
         goto TANGO
      }
      fmt.Printf("i 的值为:%v\n", i)

      i++
   }

}

执行上述代码,输出结果如下:

i 的值为:1
i 的值为:2
i 的值为:4

也可以使用 continue 关键字 和 break 关键字,但是在结构化程序中不推荐使用 goto 语句,因为这样极易造成流程混乱,降低代码的可读性。