[TOC]
Go 语言的常用流程控制有 if 和 for,而 switch 和 goto 主要是为了简化代码、降低重复代码而生的结构,属于扩展类的流程控制。
Go 语言中的基本流程控制语句,包括分支语句(if 和 switch)、循环(for)和跳转(goto)语句。还有循环控制语句(break 和 continue),前者的功能是中断循环或者跳出 switch 判断,后者的功能是继续 for 的下一个循环。
if else (分支结构)
在Go语言中可以通过 if 关键字进行条件判断,格式如下:
1 | if 表达式1 { |
Go 语言规定与 if 匹配的左括号
{
必须与 if 和表达式放在同一行,如果尝试将{
放在其他位置,将会触发编译错误。
特殊写法
Go 语言规定与 if 匹配的左括号{
必须与 if 和表达式放在同一行,如果尝试将{
放在其他位置,将会触发编译错误。
1 | if err := Connect(); err != nil { |
Connect 是一个带有返回值的函数,err:=Connect()
是一个语句,执行 Connect 后,将错误保存到 err 变量中。
err!=nil
才是 if 的判断表达式,当 err 不为空时,打印错误并返回。
循环语句for
Go语言中所有的循环类型均可以使用for 关键字来完成
基于语句和表达式的基本for 循环格式如下:
1 | for 初始语句;条件表达式;结束表达式{ |
循环体不停地进行循环,直到条件表达式返回 false 时自动退出循环,执行 for 的
}
之后的语句
for 循环可以通过 break
、goto
、return
、panic
语句强制退出循环。for 的初始语句、条件表达式、结束语句的详细介绍如下。
for 中的初始语句——开始循环时执行的语句
初始语句是在第一次循环前执行的语句,一般使用初始语句执行变量初始化,如果变量在此处被声明,其**作用域**将被局限在这个for 的范畴内
注意:初始语句可以被忽略,但是初始语句之后的分号必须填写,代码如下:
1 | stop := 2 |
这段代码将 step 放在 for 的前面进行初始化,for 中没有初始语句,此时 step 的作用域就比在初始语句中声明 step 要大。
for 中的条件表达式——控制是否循环的开关
对每次循环开始前计算的表达式,如果表达式为true ,则循环继续,否则结束循环,条件表达式可以被忽略,被忽律条件的条件表达式默认形成无限循环
结束循环时带可执行语句的无限循环
1 | var i int |
无线循环
1 | var i int |
只有一个循环条件的循环
1 | var i int |
for 中的结束语句——每次循环结束时执行的语句
在结束每次循环前执行的语句,如果循环被 break、goto、return、panic 等语句强制退出,结束语句不会被执行。
Demo 九九乘法表
1 | for x := 1; x <= 9; x++ { |
1 | 1*1=1 |
for range (键值循环)
Go 语言可以使用for range
遍历数组、切片、字符串、map 及通道(channel)。通过 for range
遍历的返回值有一定的规律:
- 数组、切片、字符串返回索引和值。
- map 返回键和值。
- 通道(channel)只返回通道内的值。
遍历数组、切片——获得索引和元素
在遍历代码中,key 和 value 分别代表切片的下标及下标对应的值。下面的代码展示如何遍历切片,数组也是类似的遍历方法:
1 | for key, value := range []int{1, 2, 3, 4} { |
遍历字符串——获得索引和元素
Go 语言和其他语言类似,可以通过 for range 的组合,对字符串进行遍历,遍历时,key 和 value 分别代表字符串的索引(base0)和字符串中的每一个字符。
1 | str := "你好,zhimma" |
代码中的 value 变量,实际类型是 rune,实际上就是 int32,以十六进制打印出来就是字符的编码。
遍历map——获得map的键和值
对于 map 类型来说,for range
遍历时,key 和 value 分别代表 map 的索引键 key 和索引对应的值,一般被称为 map 的键值对,因为它们总是一对一对的出现。下面的代码演示了如何遍历 map:
1 | family := map[string]string{ |
对 map 遍历时,遍历输出的键值是无序的,如果需要有序的键值对输出,需要对结果进行排序。
遍历通道(channel)——接收通道数据
for range
可以遍历通道(channel),但是通道在遍历时,只输出一个值,即管道内的类型对应的数据
1 | c := make(chan int) |
switch case 语句
分支选择可以理解为一种批量的if语句,使用 switch 语句可方便地对大量的值进行判断。
在 Go 语言中的 switch,不仅可以基于常量进行判断,还可以基于表达式进行判断。
基本写法
Go 语言改进了 switch 的语法设计,避免人为造成失误。Go 语言的 switch 中的每一个 case 与 case 间是独立的代码块,不需要通过 break 语句跳出当前 case 代码块以避免执行到下一行。示例代码如下:
1 | a := "hello" |
上面例子中,每个case 均是字符串格式,且使用了default 分支,Go语言规定每个 switch 只能有一个default 分支
一分支多值
当出现多个 case 要放在一起的时候,可以像下面代码这样写:
1 | var a = "mum" |
不通的 case 表达式使用逗号分隔
分支表达式
case 后不仅仅只是常量,还可以和 if 一样添加表达式,代码如下:
1 | num := 10 |
这种情况的 switch 后面不再跟判断变量,连判断的目标都没有了。
goto 语句——跳转到指定的标签
goto 语句通过标签进行代码间的无条件跳转。goto 语句可以在快速跳出循环、避免重复退出上有一定帮助,使用 goto 语句能简化一些代码的实现过程。
使用 goto 退出多层循环
多层循环中,传统方式退出
1 | package main |
使用 goto方式优化
1 | package main |
第13行 :标签只能被 goto 使用,但不影响代码执行流程,此处如果不手动返回,在不满足条件时,也会执行第 16 行代码。
使用 goto 语句后,无须额外的变量就可以快速退出所有的循环。
统一错误处理
多处错误处理存在代码重复时是非常棘手的,例如:
1 | err := firstCheckError() |
使用 goto 语句实现上面同样的逻辑:
1 | err := firstCheckError() |
break (跳出循环)
break 语句可以结束for
、switch
和select
代码块。break 语句还可以在语句后面添加标签,表示退出摸个标签对应的代码块,标签要求必须定义在对应的for
、switch
和select
的代码块上
下面看下跳出指定循环
1 | OuterLoop: |
代码输出 :
1 | 0 2 |
代码说明如下:
- 第 1 行,外层循环的标签。
- 第 2 行和第 3 行,双层循环。
- 第 5 行,使用 switch 进行数值分支判断。
- 第 8 和第 11 行,退出 OuterLoop 对应的循环之外,也就是跳转到第 1 行。
continue(中断本次循环,继续下一次循环)
continue 语句可以结束当前循环,开始下一次的循环迭代过程,仅限在 for 循环内使用
在 continue 语句后添加标签时,表示开始标签对应的循环
1 | OuterLoops: |
代码输出 :
1 | 0 2 |
第 7 行将结束当前循环,开启下一次的外层循环,而不是第 3 行的循环。