[Go 入门] 第四章 控制流程
Go 入门系列参考于互联网资料与 人民邮电出版社 《Go 语言入门经典》 与 《Effective Go》,编写目的在于学习交流,如有侵权,请联系删除
接下来将会介绍控制流程以及代码执行流程是如何确定的,本文内容:
使用 if
语句
if 语句是计算机程序的重要组成部分,if语句检查指定的条件,并在条件满足时执行指定的操作,如下1
2
3
4
5
6func main() {
b := true
if b {
fmt.Println("b is true !")
}
}
对以上代码的解读如下:
- 声明变量b并将其初始化为
true
,这个变量被推断为布尔类型 - 使用一条
if
语句判断b是否为true
- 由于这条语句
if
语句的结果为true
,因此执行大括号内的代码 - 在终端打印一行文本,指出b为
true
可执行运行多条的if
语句,运行顺序与这些语句在源代码中出现的顺序相同if
语句总是计算一个布尔表达式,在它为true
时执行大括号内的代码,在它为false
的时候则不执行
使用 else
语句
else
语句执行了到达该分支时将被执行的代码。他不做任何判断,只要达到它所在的分支就执行。大致而言,else
相当于,如果其他条件都不为true
,就执行这条语句
else
语句可用来处理前面if
语句结果不为true
的情形,如下:1
2
3
4
5
6
7
8func main() {
b := false
if b {
fmt.Println("b is true!")
} else {
fmt.Println("b is false!")
}
}
如果if
语句的结果为true
,就不会执行else
语句。else
语句指定了前面所有语句的结果都为false
时要执行的代码,只要前面有一条语句的结果为true
,它就会被忽略。
使用 else if
语句
在当需要依次判断多个布尔表达式时,可以使用else if
语句。else if
语句能够让您在前面的布尔表达式为false
时,接着判断后面的布尔表达式。
1 |
|
对以上代码的解读为:
- 声明变量i将其初始化为2
- 第一条
if
语句判断i是否为3,如果不是,就忽略下一行代码 else if
语句使用另一个布尔表达式判断i是否为2- 由于i为2,因此执行下一行代码,向终端打印一行文本
else
和else if
语句的根本不同在于,else if
语句能够让您判断布尔条件,而else
语句在到达其所在的分支时就会执行
使用比较运算符
布尔表达式只是返回true
和false
,但使用比较运算符可执行更复杂的评估,以下是比较运算符
比较运算符
字符 | 运算符 |
---|---|
== | 等于 |
!= | 不等 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
使用算数运算符
结合使用算数运算符和比较运算符来创建管理控制流程的布尔表达式
算术运算符
字符 | 运算符 |
---|---|
+ | 和(加) |
- | 差(减) |
* | 积(乘) |
/ | 商(除) |
% | 余(模) |
使用逻辑运算符
除比较运算符和算数运算符外,逻辑运算符也可以用于支持流程控制。
逻辑运算符
字符 | 运算符 |
---|---|
&& | 与:两个条件是否都为true |
|| | 或:两个条件是否至少有一个为true |
! | 非:条件是否为false |
使用 switch
语句
switch
语句可用来替代冗长的if else
布尔比较,很多程序员喜欢用switch
语句(而不使用else if
语句),从编译层面上来说,这样的代码效率也可能更高。除了少量的else if
比较外,其他的都可以替换为switch
语句,这样不仅可提高代码的可读性,还能提高效率
1 |
|
对上述代码的解读如下:
switch
语句指定了一个要评估的变量 i- 在一系列的
case
语句中指定了要与变量 i 比较的表达式 - 如果这个表达式的结果与 i 相等,就执行相应的语句
- 如果这个表达式的结果与 i 不等,就跳到下一条
case
语句 - 在这里,由于 i 为2,因此向终端打印单词 Two
相比于else if
条件,switch
语句更简洁,它还支持其他case
条件都不满足时将执行的default case
。在switch
语句中,可使用default
来指定其他case
条件都不满足时将要执行的代码,default case
通常放在switch
语句末尾,但也可以放在其他地方。
1 |
|
使用 for
语句进行循环
for
语句能够反复执行代码块,这在编程中称为循环:反复执行代码块,直到条件不再满足。如下的示例,将一个数字不断加1,直到它为特定的数字:
1 |
|
对以上代码的解读为:
- 声明变量i并将其初始化为0
- 一条
for
语句判断i是否小于10 - 如果这个布尔条件为
true
,就执行for
语句中的代码 - 使用递增运算符将变量i加1
- 将变量i的值打印到终端
- 返回到开头的布尔表达式,判断变量i的值是否小于10
- 变量i不再小于10时,这个布尔表达式将为
false
,因此不再执行for
语句中的代码,循环就此结束
包含初始化语句和后续语句的 for
语句
除要检查的条件外,for
语句还可指定在循环开始时执行的初始化语句以及后续(post)语句,这些语句可让迭代代码简短得多,但必须使用分号将他们分隔开
- 初始化语句:仅在首次迭代前执行
- 条件语句:每次迭代前都将检查的布尔表达式
- 后续语句:每次迭代后都将执行
1 |
|
对以上代码的解读为:
- 声明变量i并将其初始化为0
- 一条
for
语句检查变量i是否小于10 - 如果这个布尔表达式为
true
,就执行for
语句中的代码 - 使用递增运算符将变量i的值加1
- 将变量i的值打印到终端
- 返回到开头的布尔表达式,判断变量i的值是否小于10
- 变量i不再小于10时,这个布尔表达式将为
false
,因此不再执行for
语句中的代码,循环就此结束
包含 range
子句的 for
语句
for
语句也可用来遍历数据结构,在下面代码中,创建了一个数组,用于储存一系列数字。
1 |
|
对于上述代码的解读为:
- 声明变量numbers,并将一个包含4个整数的数组赋予给它
for
语句指定了迭代变量i,用于存储索引值,这个变量将在每次迭代结束后更新for
语句指定了迭代变量i,用于储存来自数组中的值。它也将在每次迭代结束后更新- 在循环中,打印这两个变量的值
注意事项:
迭代变量从0开始,且每次加1。要在特定的迭代中执行操作,务必从0而不是1开始计算迭代数
关于 range
:
range
类似迭代器,可以遍历数组,字符串,map等等,对象的不同,返回的结果也不同range
会复制对象,而不是不是直接在原对象上操作- 使用
range
迭代遍历引用类型时,底层的数据不会被复制
使用 defer
语句
defer
是一个很有用的Go语言功能,它能够让您在函数返回前执行另一个函数。函数遇到return
语句或达到函数末尾时返回。defer
语句通常用于执行清理操作或确保操作(如网络调用)完成后再执行另一个函数
1 |
|
对于上面的代码的解读为:
- 使用一条
defer
语句,在它所在的函数执行完毕后执行另一个函数 - 向终端打印
Hello world!
,外部函数就此结束 - 外部函数结束后,执行
defer
语句指定的函数
完成后,终端输出:1
2Hello world!
I am run after the function completes
注意:
多条defer
语句时,按照源代码中的相反顺序执行
1 |
|
执行后输出:1
2
3
4Hello world!
I am the third defer statement
I am the second defer statement
I am the first defer statement
问题列表
可以使用多种运算符(如比较运算符和算数运算符)来创建布尔表达式吗
能。布尔表达式可包含任意数量的运算符
该使用
else if
还是switch
语句else if
和switch
都是定义控制流程的合法方式。很多程序员发现,相比于使用一系列else if
,使用switch
语句编写的代码更容易理解,因此建议使用switch
语句为何要使用
defer
语句,而不直接使用常规的控制流程一些需要使用
defer
语句的例子包括:- 在读取文件后,需要将其关闭
- 收到来自 Web 服务器的响应后对其进行处理以及建立连接后向数据库请求数据
- 需要在某项工作完成后执行特定函数