Go里的流程控制方法有如下这么多种:
-
if - else 条件语句
-
switch - case 选择语句
-
for - range 循环语句
-
goto 无条件跳转语句
-
defer 延迟执行
if-else 条件语句
if 条件 1 {
分支 1
} else if 条件 2 {
分支 2
} else if 条件 ... {
分支 ...
} else {
分支 else
}
Go编译器严格要求else if (或 else)和 两边的花括号({
和 }
),必须在同一行。
由于 Go是 强类型,要求条件表达式必须严格返回布尔型的数据(nil 、 0 和 1 都不行)。
单分支判断
只有一个 if ,没有 else
import "fmt"
func main() {
age := 20
if age > 18 {
fmt.Println("已经成年了")
}
}
如果条件里需要满足多个条件,可以使用 &&
和 ||
-
&&
:表示且,左右都需要为true,最终结果才能为 true,否则为 false -
||
:表示或,左右只要有一个为true,最终结果即为true,否则 为 false
import "fmt"
func main() {
age := 20
gender := "male"
if (age > 18 && gender == "male") {
fmt.Println("是成年男性")
}
}
多分支判断
if - else 语句
import "fmt"
func main() {
age := 20
if age > 18 {
fmt.Println("已经成年了")
} else {
fmt.Println("还未成年")
}
}
if - else if - else 语句
import "fmt"
func main() {
age := 20
if age > 18 {
fmt.Println("已经成年了")
} else if age >12 {
fmt.Println("已经是青少年了")
} else {
fmt.Println("还不是青少年")
}
}
高级写法
在 if 里可以允许先运行一个表达式,取得变量后,再对其进行判断,比如:
import "fmt"
func main() {
if age := 20;age > 18 {
fmt.Println("已经成年了")
}
}
switch-case 选择语句
switch 表达式 {
case 表达式1:
代码块
case 表达式2:
代码块
case 表达式3:
代码块
case 表达式4:
代码块
case 表达式5:
代码块
default:
代码块
}
将switch 后的表达式分别和 case 后的表达式进行对比,只要有一个 case 满足条件,就会执行对应的代码块,然后直接退出 switch - case ,如果一个都没有满足,才会执行 default 的代码块。
示例
switch 后接一个你要判断变量 education
(学历),然后 case 会拿这个 变量去和它后面的表达式(可能是常量、变量、表达式等)进行判等。
如果相等,就执行相应的代码块。如果不相等,就接着下一个 case。
import "fmt"
func main() {
education := "本科"
switch education {
case "博士":
fmt.Println("我是博士")
case "研究生":
fmt.Println("我是研究生")
case "本科":
fmt.Println("我是本科生")
case "大专":
fmt.Println("我是大专生")
case "高中":
fmt.Println("我是高中生")
default:
fmt.Println("学历未达标..")
}
}
输出如下:
我是本科生
一个 case 多个条件
case 后可以接多个多个条件,多个条件之间是 或(||)
的关系,用逗号相隔。
import "fmt"
func main() {
month := 2
switch month {
case 3, 4, 5:
fmt.Println("春天")
case 6, 7, 8:
fmt.Println("夏天")
case 9, 10, 11:
fmt.Println("秋天")
case 12, 1, 2:
fmt.Println("冬天")
default:
fmt.Println("输入有误...")
}
}
输出如下:
冬天
case 条件常量不能重复
当 case 后接的是常量时,该常量只能出现一次
以下两种情况,在编译时,都会报错:duplicate case "male" in switch
错误示例一:
gender := "male"
switch gender {
case "male":
fmt.Println("男性")
// 与上面重复
case "male":
fmt.Println("男性")
case "female":
fmt.Println("女性")
}
错误示例二:
gender := "male"
switch gender {
case "male", "male":
fmt.Println("男性")
case "female":
fmt.Println("女性")
}
switch 后接函数
switch 后面可接函数,前提是 case 后的值类型与函数的返回值一致。
import "fmt"
// 判断一个同学是否有挂科记录的函数
// 返回值是布尔类型
func getResult(args ...int) bool {
for _, i := range args {
if i < 60 {
return false
}
}
return true
}
func main() {
chinese := 80
english := 50
math := 100
switch getResult(chinese, english, math) {
// case 后也必须 是布尔类型
case true:
fmt.Println("该同学所有成绩都合格")
case false:
fmt.Println("该同学有挂科记录")
}
}
switch 不接表达式
switch 后可不接任何变量、表达式、函数,此时,switch - case 就相当于 if - else if - else
score := 30
switch {
case score >= 95 && score <= 100:
fmt.Println("优秀")
case score >= 80:
fmt.Println("良好")
case score >= 60:
fmt.Println("合格")
case score >= 0:
fmt.Println("不合格")
default:
fmt.Println("输入有误...")
}
switch 的穿透能力
正常情况下 switch - case 的执行顺序是:只要有一个 case 满足条件,就会直接退出 switch - case ,如果 一个都没有满足,才会执行 default 的代码块。
例外:当 case 使用关键字 fallthrough
开启穿透能力时。
s := "hello"
switch {
case s == "hello":
fmt.Println("hello")
fallthrough
case s != "world":
fmt.Println("world")
}
输出如下:
hello
world
需要注意的是:fallthrough 只能穿透一层,意思是它只给一次再判断case的机会,不管有没有匹配上,执行后都要退出:
s := "hello"
switch {
case s == "hello":
fmt.Println("hello")
fallthrough
case s != "xxxx":
fmt.Println("xxxx")
case s != "world":
fmt.Println("world")
}
输出如下,并不会输出 world(即使它符合条件):
hello
xxxx
for 循环语句
for 循环格式:
for [condition | ( init; condition; increment ) | Range | 不接表达式]
{
statement(s);
}
for 后面,可以接三种类型的表达式:
-
接一个条件表达式
-
接三个表达式
-
接一个 range 表达式
-
不接表达式
接一个条件表达式
这个例子会打印 1 到 5 的数值。
import "fmt"
func main() {
a := 1
for a <= 5 {
fmt.Println(a)
a ++
}
}
输出如下:
1
2
3
4
5
接三个表达式
for 后面,紧接着三个表达式,使用 ;
分隔:
-
第一个表达式:初始化控制变量,在整个循环生命周期内,只运行一次;
-
第二个表达式:设置循环控制条件,当返回true,继续循环,返回false,结束循环;
-
第三个表达式:每次循完开始(除第一次)时,给控制变量增量或减量。
这边的例子和上面的例子,是等价的。
import "fmt"
func main() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
}
输出如下:
1
2
3
4
5
不接表达式:无限循环
在 Go 语言中,没有 while 循环,使用 for 来实现实现无限循环。
当你不加任何的判断条件时, 就相当于你每次的判断都为 true,程序就会一直处于运行状态,但是一般我们并不会让程序处于死循环,在满足一定的条件下,可以使用关键字break
退出循环体,也可以使用 continue
直接跳到下一循环。
下面两种写法都是无限循环的写法。
for {
代码块
}
// 等价于
for ;; {
代码块
}
举个栗子:
import "fmt"
func main() {
var i int = 1
for {
if i > 5 {
break
}
fmt.Printf("hello, %d\n", i)
i++
}
}
输出如下:
hello, 1
hello, 2
hello, 3
hello, 4
hello, 5
接 for-range 语句
在 Go 可以使用 for-range 的方式来实现遍历一个可迭代对象。range 后可接数组、切片,字符串等
由于 range 会返回两个值:索引和数据,用不到的返回值使用下划线 _
表示 :
import "fmt"
func main() {
myarr := [...]string{"world", "python", "go"}
for _, item := range myarr {
fmt.Printf("hello, %s\n", item)
}
}
输出如下:
hello, world
hello, python
hello, go
goto
goto
顾言思义,是跳转的意思。
goto 后接一个下一步要执行哪里的代码的标签,模型如下:
goto 标签;
...
...
标签: 表达式;
示例
goto
可以打破原有代码执行顺序,直接跳转到某一行执行代码:
import "fmt"
func main() {
goto flag
fmt.Println("B")
flag:
fmt.Println("A")
}
输出如下:
执行结果,并不会输出 B ,而只会输出 A
如何使用
goto
语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
举个栗子,用 goto
的方式来实现一个打印 1到5 的循环。
import "fmt"
func main() {
i := 1
flag:
if i <= 5 {
fmt.Println(i)
i++
goto flag
}
}
输出如下:
1
2
3
4
5
举个栗子,使用 goto 实现 类型 break
的效果。
import "fmt"
func main() {
i := 1
for {
if i > 5 {
goto flag
}
fmt.Println(i)
i++
}
flag:
}
输出如下
1
2
3
4
5
再举个栗子,使用 goto 实现 类型 continue
的效果,打印 1到10 的所有偶数。
import "fmt"
func main() {
i := 1
flag:
for i <= 10 {
if i%2 == 1 {
i++
goto flag
}
fmt.Println(i)
i++
}
}
输出如下
2
4
6
8
10
注意事项
goto语句与标签之间不能有变量声明,否则编译错误。
import "fmt"
func main() {
fmt.Println("start")
goto flag
var say = "hello oldboy"
fmt.Println(say)
flag:
fmt.Println("end")
}
编译错误
.\main.go:7:7: goto flag jumps over declaration of say at .\main.go:8:6