5.1 程序流程控制
主要有三大流程控制语句:顺序控制、分支控制、循环控制。
5.1.1 顺序控制
- 程序从上到下逐行地执行,中间没有任何判读和跳转。
- 注意事项:Go中定义变量时采用合法的前向引用,即变量要先定义再使用。
5.1.2 分支控制
(1)单分支控制
if 条件表达式 {
执行代码块
}
说明:Go语言中,{}的位置只能有一种情况({不能另起一行),且不能省略,否则会出错。因为Go语言的设计者只希望每个问题只有一种解决方式。
Go支持在if中,直接定义一个变量,如:
if age := 20; age > 18 {
.....
}
(2)双分支控制
if 条件表达式 {
执行代码块1
} else {
执行代码块2
}
(3)多分支控制
if 条件表达式1 {
执行代码块1
} else if 条件表达式2 {
执行代码块2
}
......
} else {
执行代码块 n
}
(4)嵌套分支
if 条件表达式1 {
if 条件表达式2 {
执行代码块1
} else {
执行代码块2
}
}
(5)switch分支控制
swtich语句用于基于不同条件执行不同动作,每一个case分支都是唯一的,从上到下逐一测试,直到匹配为止,匹配项后面也不需要再加break。
switch 表达式 {
case 表达式1, 表达式2, ... :
语句块1
case 表达式3, 表达式4, ... :
语句块2
...
default:
语句块n
}
注意事项:
- case/switch后是一个表达式(即:常量值、变量、一个有返回值的函数等都可以)
- case后的各个表达式的值的数据类型,必须和switch的表达式数据类型一致
- case后面可以带多个表达式,使用逗号间隔
- case后面的表达式如果是常量值,则要求不能重复
- case后面不需要带break,如果匹配到一个case执行相应代码块后会自动退出switch,如果不匹配则会执行default语句后退出
- default不是必须的
- switch后也可以直接声明/定义一个变量,分号结束(不推荐)
switch grade := 90; {
case grade > 90 :
...
case grade >= 70 :
...
default:
...
}
- switch后也可以不带表达式,类似if-else分支来使用
switch{
case age == 10:
....
case age == 20:
...
default :
...
}
- switch穿透-fallthrough,如果在case语句块后增加fallthrough,则会继续执行下一个case,也叫switch穿透
var num int = 10
switch num {
case 10:
...
fallthrough //默认只穿透一层
case 20:
...
fallthrough
case 30 :
...
default:
...
}
- Type Switch:switch语句还可以被用于type-switch来判断某个interface变量中实际指向的变量类型
var x interface{}
var y = 10.0
x = y
switch i := x.(type) {
case nil:
fmt.Printf("x的类型:%T", i)
case int:
fmt.Printf("x是int型")
case float64:
fmt.Printf("x是float64型")
case func(int) float64:
fmt.Printf("x是func(int)型")
case bool, string:
fmt.Printf("x是bool或string型")
}
switch和if的比较:
- 如果判断的具体数值不多,且符号整数、浮点数、字符、字符串这几种类型,建议使用switch语句,简洁高效。
- 其他情况,对区间判断和结果为bool类型的判断,使用if。
5.1.3 循环控制
(1)for循环控制
for 循环遍历初始化; 循环条件; 循环变量迭代 {
循环操作(语句)
}
//实例
for i := 1; i <= 10; i++ {
.....
}
注意事项:
- 循环条件是返回一个布尔值的表达式
- for循环的第二种使用方式
for 循环判断条件 {
//循环执行语句
}
将变量初始化和变量迭代写到其他位置,如:
j := 1
for j <= 10 {
....
j++
}
- for循环的第三种使用方式
for {
//循环执行语句
}
上面的写法等价于for ; ; {}
是一个无限循环,需要配合break语句使用。
k := 1
for {
if k <= 10 {
...
} else {
break;
}
k++
}
- Go提供for-range的方式,可以方便遍历字符串和数组
str = "abc-ok"
for index, val := range str {
fmt.Printf("index = %d, val = %c \n", index, val)
}
(2)while和do…wihle的实现
Go语言没有while和do…while语法,但是可以通过for循环来实现效果。
- while循环的实现
for {
if 循环条件表达式 {
break //跳出for循环
}
循环操作(语句)
循环变量迭代
}
- do…while的实现
for {
循环操作(语句)
循环变量迭代
if 循环条件表达式 {
break //跳出for循环
}
}
(3)多重循环控制
将一个循环放在另一个循环体内,就形成了嵌套循环。在外边的for称为外层循环在里面的for循环称为内层循环。
实际上,嵌套循环就是把内层循环当做外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当前循环,开始下一次的循环。
5.2 跳转控制语句
(1)break/continue
break/continue语句都可以添加标签指定需要终止的是哪一层的语句块/需要跳过的是哪一层循环。如:
label://标签
for i := 0; i < 4; i++ {
label1:
for j := 0; j < 10; j++ {
if j == 2 {
break label2
}
....
}
}
(2)goto
Go语言的goto语句可以无条件地转移到程序中指定的行。
通常与条件语句配合使用,可以实现条件转移。但是一般不主张使用goto语句。
goto label
...
label:statement
(3)return
如果return是在普通的函数,则表示跳出该函数;如果return是在main函数,表示终止main函数,即终止程序。