Go语言中的流程控制
流程控制主要用于设定计算执行的顺序,简历程序的逻辑结果,Go语言的流程控制语句与其他语言类似,支持如下几种流程控制语句:
-
条件语句:用于条件判断,对应的关键字有if、else和else if;
-
分支语句:用于分支选择,对应的关键字有switch、case和select(用于通道);
-
循环语句:用于循环迭代,对应的关键字有for和range;
-
跳转语句:用于代码跳转,对应的关键字有goto。
1 条件语句
条件语句的示例模板:
// if
if condition {
// do something
}
// if...else...
if condition {
// do something
} else {
// do something
}
// if...else if...else...
if condition1 {
// do something
} else if condition2 {
// do something else
} else {
// catch-all or default
}
注意以下几点:
-
条件语句不需要使用括号
()
将条件包含起来; -
无论语句体内有几条语句,花括号
{}
都是必须存在的; -
左花括号
{
必须与 if 或者 else 处于同一行; -
在 if 之后,条件语句之前,可以添加变量初始化语句,使用
;
间隔,例如:if score := 100;score > 90 {
。
以下是一个简单的条件语句代码示例:
score := 100
if score > 85 {
fmt.Println("优秀")
} else if score > 70 {
fmt.Println("良好")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
2 分支语句
分支语句会根据传入条件的不同,选择不同的分支代码执行。
分支语句的示例模板:
switch var1 {
case val1:
...
case val2:
...
case val3,val4:
...
case val5:
...
fallthrough // 添加该语句
default:
...
}
注意以下几点:
-
和条件语句一样,左花括号
{
必须与switch
处于一行; -
单个
case
中,可以出现多个结果选项(通过逗号分隔); -
Go语言中的分支语句不需要break来明确退出一个case;
-
只有在case中明确添加 fallthrough 关键字,才会继续执行紧跟着的下一个case语句;
-
可以不设定 switch 之后条件表达式,这种情况下,整个 switch 结构与多个if...else...的逻辑作用等同。
一个简单的分支语句示例:
score := 100
switch {
case score > 85:
fmt.Println("优秀")
case score > 70 && score <= 85:
fmt.Println("良好")
case score >= 60 && score <= 70:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
Go语言中,可以通过逗号分隔不同的分支条件达到合并分支的目的,如 case 90,100,而不能像其他语言一样,通过相邻的case语句来进行分支的合并,这是因为Go语言不需要通过break退出某个分支,上一个case分支语句执行结束后,会自动进行退出,如果一定要执行后续的case语句,可以通过fallthrough语句来声明。
month := 1
switch month {
case 3, 4, 5:
fmt.Println("春季")
case 6, 7, 8:
fmt.Println("夏季")
case 9, 10, 11:
fmt.Println("秋季")
case 12:
fmt.Println("冬季")
fallthrough
case 1, 2:
fmt.Println("冬季")
}
3 循环语句
Go语言中使用循环语句,需要注意以下几点:
-
和条件语句、分支语句一样,左花括号
{
必须与for处于同一行; -
只支持for关键字循环语句,不支持while和do-while结构的循环语句;
-
可以通过for-range结构对可迭代的集合进行遍历;
-
支持基于条件判断进行循环迭代;
-
允许在循环条件中定义和初始化变量,且支持多重赋值;
-
Go语言的for循环同样支持continue和break来控制循环,但是它提供了一个更高级的break,可以选择中断哪一个循环。
3.1 for循环
Go语言的循环语句只支持 for 关键字,而不支持 while 和 do-while 结构,Go语言中,for循环的循环条件不包含括号,示例代码如下:
sum := 0
for i :1; i <= 100; i++ {
sum += i
}
fmt.Println(sum)
3.2 无限循环
Go语言仅支持for循环,针对无限循环的场景,可以通过不带循环条件的for循环实现,代码如下:
// 不指定循环语句,直接进行for循环,通过break退出循环语句
sum2 := 0
j := 0
for {
j++
if j > 100 {
break
}
sum2 += j
}
3.3 多重循环
for 循环的条件表达式也支持多重赋值,可以实现数组/切片首尾元素的交换,代码如下:
array := []int{1, 2, 3, 4, 5, 6} for i, j := 0, len(array)-1; i < j; i, j = i+1, j-1 { array[i], array[j] = array[j], array[i] } fmt.Println(array)
3.4 for-range结构
Go语言中支持通过for-range结构对于可迭代的集合(数组、切片、字典)进行循环遍历,使用方式如下:
array := []int{1, 2, 3, 4, 5, 6}
for k, v := range array {
fmt.Println(k, v)
}
也可以只获取键,或者只获取值,代码示例如下:
// 只获取键
for k := range array {
fmt.Printf("%d ", k)
}
// 只获取值
for _, v := range array {
fmt.Printf("%d ", v)
}
3.5 基于条件判断循环
只有满足指定的条件才会执行循环体中的代码,代码示例如下:
sum := 0
i := 0
for i < 100 {
i++
sum += i
}
fmt.Println(sum)
4 跳转语句
4.1 break与continue语句
Go语言支持在循环语句中通过break语句跳出循环,通过continue语句进入下一个循环。
break语句代码示例:
sum := 0
i := 0
for {
i++
if i > 100 {
break
}
sum += i
}
continue语句代码示例:
for i = 0; i < 5; i++ {
if i%2 == 0 {
continue
}
fmt.Printf("%d ", i)
}
4.2 标签
Go语言中的break和continue支持与标签结合跳转到指定的标签语句,标签通过 标签名 :
进行声明:
break 标签代码示例:
arr := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
ITERATOR1:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
num := arr[i][j]
if j > 1 {
break ITERATOR1
}
fmt.Println(num)
}
}
如上所示,当j>1,此时循环执行到arr[0,2],直接跳到标签ITERATOR1的位置,也即跳出了外层循环,同样的语句换成continue再次执行:
arr := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
ITERATOR1:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
num := arr[i][j]
if j > 1 {
continue ITERATOR1
}
fmt.Println(num)
}
}
4.3 goto语句
goto语句并不建议使用,因为很容易造成代码的逻辑混乱,导致难以发现的Bug,代码示例如下:
arr := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
num := arr[i][j]
if j > 1 {
goto EXIT
}
fmt.Println(num)
}
}
EXIT:
fmt.Println("EXIT.")