## 1 概述
Go语言提供了条件分支 if,状态分支 switch,循环 for,跳转 goto,延迟执行 defer,这些流程控制语句。分别作说明如下:
## 2 条件分支 if
依据条件是否满足确定执行哪个分支。
语法:
```
if 条件 1 {
分支 1
} else if 条件 2 {
分支 2
} else if 条件 ... {
分支 ...
} else {
分支 else
}
```
流程图:
![if](http://www.hellokang.net/images/posts/go/go-if.png)
Go是强类型,要求条件表达式严格返回布尔型数据!
## 3 状态分支 switch
### 3.1 基础
状态分支,依据特定的状态值进行分支判断。
语法:
```
switch 分支测试表达式 {
case 状态1:
分支1
case 状态2:
分支2
case 状态...:
分支...
default:
分支 default
}
```
流程如下:
![for](http://www.hellokang.net/images/posts/go/go-switch.png)
### 3.2 fallthrough,向下穿越
在其他语法(非Go,C,PHP)中,switch 有一个特定的现象,就是向下穿越,指的是一旦一个分支 case 满足,则后续分支代码都会被执行。而Go语言中,默认分支执行完毕,switch 执行完毕。使用 fallthrough 语法,可以达到穿越下一个 case 分支的目的。
fallthrough 需要出现在分支语句块的最后一句!
语法:
```
switch 分支测试表达式 {
case 状态1:
分支1
fallthrough
case 状态2:
分支2
fallthrough
default:
分支 default
}
```
流程如下:
![switch-fallthrough](http://www.hellokang.net/images/posts/go/go-switch-fallthrough.png)
### 3.3 条件型 switch
示例代码,逻辑与 if-else-if 一致:
```
score := 89
switch {
case score >= 90:
fmt.Println("优秀,不错")
case score >= 80:
fmt.Println("还行吧")
default:
fmt.Println("呵呵")
}
```
个人感觉失去了 switch 分支的意义哈!
## 4 循环for
### 4.1 基本
语法格式:
```
for 初始化语句; 条件语句; 条件变化语句 {
循环体
}
// 输出1-10
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
```
流程如下:
![for](http://www.hellokang.net/images/posts/go/go-for.png)
### 4.2 省略语句
Go中允许省略三个语句中的任意,就是可以形成如下的语法:
仅存在条件语句,类似其他语言的 while 结构!
```
for 条件语句 {
循环体
}
```
无限循环结构,死循环
```
for {
循环体
}
```
其他结构,三个语句可以任意省略,不再列举:
```
for ; 条件语句; 条件变化语句 {
循环体
}
for 初始化语句; 条件语句; {
循环体
}
```
### 4.3 break
终止整个循环执行。
流程图如下:
![for-break](http://www.hellokang.net/images/posts/go/go-for-break.png)
### 4.4 continue
终止本次循环体的继续执行,进行循环条件变化。
流程如下:
![for-continue](http://www.hellokang.net/images/posts/go/go-for-continue.png)
### 4.5 嵌套循环
语法:
```
for {
for {
}
}
```
在使用 break,continue 时,若需要终止外层循环 for,需要配合语句标签使用,演示如下:
```
userLabel:
for {
for {
break userLabel
或者
continue userLabel
}
}
```
额外注意,switch 在语言中,被视为执行一次的循环结构,因此 switch 中若要终止外层循环,需要使用标签语法,不能直接 break、continue,演示如下:
```
userLabel:
for {
swtich variable {
case "exit"
break userLabel
或者
continue userLabel
}
}
```
### 5 goto
配合标签完成无条件跳转。演示如下:
```
if error {
goto doError
}
// 其他业务逻辑代码略
doError:
fmt.Println(errorInfo)
```
## 6 延迟执行defer
defer 语句会将其后语句进行延迟处理。在 defer 所属函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。演示如下:
```
func main() {
fmt.Println("before defer")
defer fmt.Println("defer A")
defer fmt.Println("defer B")
defer fmt.Println("defer C")
fmt.Println("after defer")
}
以上代码的执行结果:
before defer
after defer
defer C
defer B
defer A
```
defer 执行是放在一个临时的调用栈中,因此是先入栈后出栈的。
流程图如下:
![defer](http://www.hellokang.net/images/posts/go/go-defer.png)
实操时,处理互斥所时,很常用!
完!
原文出自:[小韩说课](http://www.hellokang.net/go/go-flow-control/)
微信关注:小韩说课
![小韩说课](http://www.hellokang.net/images/wechat_subscription.jpg)
有疑问加站长微信联系(非本文作者))