程序设计语言的流程控制语句用于设定计算执行的次序,建立程序的逻辑结构。流程控制语句主要有三个作用:

  • 选择:根据条件跳转到不同的执行序列
  • 循环:根据条件反复执行某段语句序列
  • 跳转:根据条件跳转到某执行序列

Go 语言支持以下几种流程控制语句:

  • 条件语句:对应关键字为 if、else、else if
  • 选择语句:对应关键字为 switch、case、select
  • 循环语句:对应关键字为 for、range
  • 跳转语句:对应关键字为 goto

1. 条件语句

1
2
3
4
5
6
a := 4
if b := 1; a < 5 {
a = a + b
} else {
a = a -b
}
  • 条件语句不需要使用圆括号 ( ) 将条件包含起来
  • 无论语句体包含几条语句,花括号 { } 必须存在,且遵守 go 语言代码风格
  • 在 if 之后条件语句之前,可以添加变量初始化语句,用 ; 分隔开
  • 在有返回值的函数中,不允许将最终的 return 语句包含在 if … else … 结构中

2. 选择语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch a {
case 0:
fallthrough
case 1:
fmt.Println(">= 0 and <2")
case 2:
fallthrough
case 3:
fallthrough
case 4:
fmt.Println(">=2 and < 5")
default:
fmt.Println("< 0 or >= 5")
}
  • switch 后的表达式不限制为常量或整数
  • 单个 case 中可以出现多个结果选项
  • Go 语句不需要使用 break 来明确退出一个 case;相反,只有在 case 中明确添加 fallthrough 关键字,才会继续执行紧跟的下一个 case
  • 可以不设定 switch 后的表达式,在这种情况下,整个 switch 结构与多个 if … else … 的逻辑作用相同
1
2
3
4
5
6
7
8
switch {
case 0 <= a && a < 2:
fmt.Println(">= 0 and <2")
case 2 <= a && a < 5:
fmt.Println(">=2 and < 5")
case 5 < a || a < 0:
fmt.Println("< 0 or >= 5")
}

3. 循环语句

Go 语句并不支持 C 语言中的 while 和 do-while 语句,只支持 for 语句。

3.1 for 第一种格式

for 语句第一个格式如下:

1
2
3
for initialization; condition; post {
// zero or more statements
}
  • initalization如果存在,必须是一条简单语句( simple statement) ,即:短变量声明、自增语句、赋值语句或函数调用。
  • for循环的这三个部分每个都可以省略,如果省略 initialization 和 post ,分号也可以省略;此时相当于 C 语言中的 while(condition) { } 。
1
2
3
4
// a traditional "while" loop
for condition {
// ...
}
  • condition 也可以省略;此时相当于 C 语言中的 for ( ; ; ) { } 。
1
2
3
4
// a traditional infinite loop
for {
// ...
}

3.2 for 第二种格式

Go 语言中的 for 循环的另一种形式, 在某种数据类型的区间( range) 上遍历。

1
2
3
4
5
6
7
a := []int{1,2,3,4,5,6}
for i,j := 0, len(a)-1; i < j; i,j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
for _, v := range a {
fmt.Println(v)
}

其中,range 关键字用来便利数组切片的所有元素。range 表达式返回值有两个,第一个是索引,第二个是索引处的元素值。

3.3 注意事项

  • Go 语言中的 for 循环与 C 语言一样,都允许在循环条件中定义和初始化变量,唯一的区别是在于 Go 语言不支持以逗号为间隔的多个赋值语句,而必须使用平行/多重赋值的方式来初始化多个变量。
  • Go 语言中的 for 循环同样支持 continue 和 break 来控制循环,但是它提供了一个更高级的 break 和 continue,可以选择跳出/继续执行哪一层循环(Label 需要在要跳出/继续执行的 for 循环语句前声明)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sum := 0
JLoop: //对于 break 而言是跳出最外层循环;对于 continue 是继续执行下一次最外层循环
for {
for j := 0; j < 10; j++ {
sum += j
if sum > 100 {
break JLoop
} else {
fmt.Println("j=",j)
continue JLoop
}
}
}
fmt.Println(sum)

4. 跳转语句

Go 语言提供了 goto 语句,用于跳转到程序中某个标签。goto 语句、break 语句、continue 语句可以共用同一标签,但三者含义不同:

  • goto 是跳转到标签处执行
  • break 是跳出到标签指定的循环体外
  • continue 是继续下一次执行标签指定的循环体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sum := 0
JLoop:
for {
sum += 10
for j := 0; j < 10; j++ {
sum += j
if sum > 100 {
break JLoop
} else {
fmt.Println("j=",j)
continue JLoop
}
}
}
fmt.Println(sum)
if sum < 150 {
goto JLoop
} else {
fmt.Println("sum=",sum)
}

最终运行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
j= 0
j= 0
j= 0
j= 0
j= 0
j= 0
j= 0
j= 0
j= 0
j= 0
110
120
130
140
150
sum= 150