4 流程控制和运算符
Go 语言中常用的流程控制有 if 和 for。而 switch 和 goto 主要是为了简化代码、降低重复代码而生的结构,属于扩展类的流程控制。
4.1 if 语句
4.1.1 if 语句的基本格式
1 2 3 4 5 6 7
| if 表达式1 { 分支1 } else if 表达式2 { 分支2 } else { 分支3 }
|
4.1.2 if 的特殊写法
1 2 3 4 5 6 7 8
| if score := 65; score >= 90 { fmt.Println("A") } else if score > 75 { fmt.Println("B") } else { fmt.Println("C") }
|
4.2 for 语句
go 语言中所有的循环类型都可以使用 for 关键字来完成。
4.2.1 for 基本格式
1 2 3
| for 初始语句; 条件表达式; 结束语句 { 循环体语句 }
|
1 2 3
| for i := 0; i < 10; i++ { fmt.Println(i) }
|
4.2.2 省略初始值的样式
初始语句可以被省略,但初始语句后的分号不能被省略
1 2 3 4
| i := 0 for ; i < 5; i++ { fmt.Println(i) }
|
4.2.3 省略初始语句和结束语句
1 2 3 4 5
| i := 0 for i < 5 { fmt.Println(i) i++ }
|
4.2.4 死循环
4.2.5 for range
Go 语言中可以使用 for range 遍历数组、切片、字符串、map 以及通道(channel).通过 for range 遍历的返回值有如下规律:
- 数组、切片、字符串返回索引和值
- map 返回键和值
- 通道(channel)只返回通道中的值
1 2 3 4 5 6 7 8 9 10 11 12
| package main
import ( "fmt" )
func main() { str := "hello,中国" for index, value := range str { fmt.Printf("%d %c\n", index, value) } }
|
输出结果如下:
1 2 3 4 5 6 7 8
| 0 h 1 e 2 l 3 l 4 o 5 , 6 中 9 国
|
上述示例中,由于中和国占3个字节,所以,国的索引从 9 开始。
4.2.6 跳出 for 循环——break
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package main
import ( "fmt" )
func main() { for i := 0; i < 10; i++ { if i == 5 { break } fmt.Println(i) } fmt.Println("循环结束") }
|
输出结果为:
4.2.7 跳过某次循环——continue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package main
import ( "fmt" )
func main() { for i := 0; i < 10; i++ { if i == 5 { continue } fmt.Println(i) } fmt.Println("循环结束") }
|
输出结果为:
4.3 switch 语句
4.3.1 switch 基本写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package main
import ( "fmt" )
func main() { finger := 3 switch finger { case 1: fmt.Println("大拇指") case 2: fmt.Println("食指") case 3: fmt.Println("中指") case 4: fmt.Println("无名指") case 5: fmt.Println("小拇指") default: fmt.Println("输入无效") } }
|
4.3.2 一个分支有多个值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package main
import ( "fmt" )
func main() {
switch n := 3; n { case 1, 3, 5, 7, 9: fmt.Println("奇数") case 2, 4, 6, 8: fmt.Println("偶数") default: fmt.Println("其他数值") } }
|
4.3.3 case 语句可以是表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package main
import ( "fmt" )
func main() {
age := 3 switch { case age < 18: fmt.Println("未成年人") case age > 50: fmt.Println("老年人") default: fmt.Println("中年人") } }
|
4.3.3 case 语句穿透–fallthrough
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import ( "fmt" )
func main() { s := "a"
switch { case s == "a": fmt.Println("a") fallthrough case s == "b": fmt.Println("b") case s == "c": fmt.Println("c") default: fmt.Println("其他字符") } }
|
输出结果:
因为语句中使用了 fallthrough,所以打印完 a 之后还会打印一个 b
4.4 goto
goto 语句通过标签进行代码间的无条件跳转。goto 常用于快速跳出循环、避免重复退出。
4.4.1 快速跳出双层循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package main
import ( "fmt" )
func main() { var breakFlag bool for i := 0; i < 10; i++ { for j := 0; j < 5; j++ { if j == 3 { breakFlag = true break } fmt.Printf("内存循环的值 %d", j) } if breakFlag { break } fmt.Printf("外层循环的值 %d", i) } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import ( "fmt" )
func main() {
for i := 0; i < 10; i++ { for j := 0; j < 5; j++ { if j == 3 { goto myBreakTag } fmt.Printf("内存循环的值 %d \n", j) } fmt.Printf("外层循环的值 %d \n", i) }
myBreakTag: fmt.Println("使用 goto 快速跳出双层循环,并指向自定义的 TAG") }
|
运行结果:
1 2 3 4
| 内存循环的值 0 内存循环的值 1 内存循环的值 2 使用 goto 快速跳出双层循环,并指向自定义的 TAG
|