Go语言基础之IF控制结构
Go语言基础之IF控制结构
作为一名程序员,应该都听过“程序=数据结构+算法”这一公式吧?它是由著名的计算机看科学家尼古拉斯·沃斯提出的。
在之前的文章中,我们了解了Go语言的基本数据类型和复合数据类型,他们对应的就是数据结构。在本篇文章中将介绍Go语言的控制结构,控制结构是算法的基础,再复杂的算法都可以通过分支、循环、顺序这三种控制结构来进行构造。
在Go语言中,顺序结构就不说了,针对程序的分支控制,Go语言提供了if
和switch-case
两种语句形式。而针对循环结构,Go语言只提供了for
这一循环控制语句。
IF语句基础
在前面我们了解到Go语言是基于C语言发展起来的,它继承了C语言许多语法,同时也摒弃了许多糟粕,这里也包括控制结构。下面举一些Go语言在控制结构主要的改进和优化:
- 只保留了 for 这一种循环结构,去掉了 C 语言中的 while 和 do-while 循环结构;
- 填平了 C 语言中 switch 分支结构中每个 case 语句都要以 break 收尾的“坑”;
- 支持了 type switch 特性,让“类型”信息也可以作为分支选择的条件;
- switch 控制结构的 case 语句还支持表达式列表,让相同处理逻辑的多个分支可以合并为一个分支;
- ……
IF单分支控制结构
if单分支控制结构是Go中最常用、最简单的一种分支控制结构,它根据布尔表达式的值在两个分支中选择一个执行。
1 | if boolean_expression { |
分支结构是传统结构化程序设计中的基础构件,这个 if 语句中的代码执行流程就等价于下面这幅流程图:
代码执行过程中遇到if分支后,首先判断if中的布尔表达式,如果结果为true则进入新分支,否则继续按照原分支执行。
Go语言的IF分支语句特点:
- 和 Go 函数一样,if 语句的分支代码块的左大括号与 if 关键字在同一行上;
- if 语句的布尔表达式整体不需要用括号包裹;
- if关键字后的表达式结果要么为true,要么为false,不能有其他值;
1 | import ( |
当判断条件较多,可以采用逻辑操作符对多个判断条件进行连接:
1 | if (runtime.GOOS == "linux") && (runtime.GOARCH == "amd64") && (runtime.Compiler != "gccgo") { |
此外,在使用逻辑操作符的时候还需要注意操作符的优先级:
1 | func main() { |
最一劳永逸的方法就是通过括号将不同的逻辑表达式分隔开,这样既不需要关心操作符优先级,又提高了代码的可读性。
IF二分支、多分支结构
二分支结构,当 boolean_expression 求值为 true 时,执行分支 1,否则,执行分支 2:
1 |
|
多分支结构则显得更加繁琐点,相当于是一个层层缩进的二分之结构,代码可读性较差:
1 |
|
IF语句自用变量
在IF控制结构中,我们可以在if后的布尔表达式前进行一些变量的声明,这些声明的变量作用域只能是在if语句块内部使用,所以被称之为if语句的自用变量。代码如下:
1 | func main() { |
IF语句的编写原则——“HAPPY PATH”
在日常编码中,过多的使用二分之或多分支结构对代码的可读性影响很大,同时也会降低代码的可维护性。对此,Go社区推荐我们在使用IF语句的时候,尽量使用快乐路径原则(happy path),它对if分支结构的要求特点如下:
- 仅使用单分支控制结构;
- 当布尔表达式求值为 false 时,也就是出现错误时,在单分支中快速返回;
- 正常成功的逻辑在代码布局上始终“靠左”,这样可以从上到下一眼看到该函数正常逻辑的全貌;
- 函数执行到最后一行代表一种成功状态;
具体代码如下面的代码1所示:
1 |
|
对于不符合该原则的if语句块,我们可以按照下面步骤进行重构:
- 尝试将“正常成功逻辑”提取出来,放到“快乐路径”中;
- 如果无法做到上一点,很可能是函数内的逻辑过于复杂,可以将深度缩进到 else 分支中的代码析出到一个函数中,再对原函数实施“快乐路径”原则。
思考题
如果一个 if 语句使用了多分支结构,如下面代码这样,那么 if 语句中的几个布尔表达式如何排列能达到最好的效果呢?
提示一下,几个布尔表达式能够被命中的概率是不同的,你在答案中可以自行假设一下。
各位大佬可以在评论区回答哦,回答有惊喜哦~
1 | func foo() { |
预告
下一篇:Go在常量上的设计创新