Go里的流程控制有以下几种:
if - else 条件语句
switch - case 选择语句
for - range 循环语句
goto 无条件跳转语句
defer 延迟执行
if-else
基本用法
funcTestIfElse(conditionstring){ifcondition=="1"{fmt.Println("ONE")}elseifcondition=="2"{fmt.Println("TWO")}elseifcondition=="3"{fmt.Println("THREE")}else{fmt.Println("OTHER")}}funcExecute(){TestIfElse("1")}
高级写法
在 if 里可以允许先运行一个表达式,取得变量后,再对其进行判断,比如第一个例子里代码也可以写成这样
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}
Go语言明确不支持三元表达式
switch-case
简单用法
拿 switch 后的表达式分别和 case 后的表达式进行对比,只要有一个 case 满足条件,就会执行对应的代码块,然后直接退出 switch - case ,如果 一个都没有满足,才会执行 default 的代码块。
funcTestSwitchCase(){condition:="CASE1"switchcondition{case"CASE1":fmt.Println("CASE1PRINT")case"CASE2":fmt.Println("CASE2PRINT")default:fmt.Println("DEFAULTPRINT")}}
一个case多个条件
case后接多个条件
funcTestSwitchCase(){condition:="CASE2"switchcondition{case"CASE1","CASE3","CASE5":fmt.Println("ODDPRINT")case"CASE2","CASE4","CASE6":fmt.Println("EVENPRINT")default:fmt.Println("DEFAULTPRINT")}}
case后的常量不能重复,不然会报错
duplicate case “XXX” in switch
switch接函数
switch 后面可以接一个函数,只要保证 case 后的值类型与函数的返回值 一致即可
funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}funcTestSwitchCaseFunc(){switchGetCondition("ONE"){case1:fmt.Print("ONEPRINT")case0:fmt.Print("TWOPRINT")default:fmt.Print("DEFAULT")}}
switch可以不接表达式,不接任何东西时相当于if-elseif-else
score:=30switch{casescore>=95&&score<=100:fmt.Println("优秀")casescore>=80:fmt.Println("良好")casescore>=60:fmt.Println("合格")casescore>=0:fmt.Println("不合格")default:fmt.Println("输入有误...")}
switch的穿透能力
正常情况下 switch - case 的执行顺序是:只要有一个 case 满足条件,就会直接退出 switch - case ,如果 一个都没有满足,才会执行 default 的代码块。
但是有一种情况是例外。
那就是当 case 使用关键字 fallthrough
开启穿透能力的时候。
funcTestSwitchFallThrough(){condition:="CASE1"switchcondition{case"CASE1","CASE3","CASE5":fmt.Println("ODDPRINT")fallthroughcase"CASE2","CASE4","CASE6":fmt.Println("EVENPRINT")default:fmt.Println("DEFAULTPRINT")}}//输出结果为ODDPRINTEVENPRINT
fallthrough
只能穿透一层
for循环
语法规则
for[condition|(init;condition;increment)|Range]{statement(s);}
for后面可以接:
condition
[一个条件表达式]
( init; condition; increment )
[最常见的]
Range
range表达式
什么都不接
样例
funcTestFor(){a:=1fora<=5{fmt.Printf("a:%v\n",a)a++}fori:=1;i<=5;i++{fmt.Printf("i:%v\n",i)}rangeArr:=[]string{"C1","C2","C3"}for_,item:=rangerangeArr{fmt.Printf("item:%v\n",item)}number:=0for{ifnumber>=5{break}fmt.Printf("number:%v\n",number)number++}}
输出
a:1a:2a:3a:4a:5i:1i:2i:3i:4i:5item:C1item:C2item:C3number:0number:1number:2number:3number:4
go无条件跳转
语法规则
goto
后接一个标签,这个标签的意义是告诉 Go程序下一步要执行哪里的代码。
所以这个标签如何放置,放置在哪里,是 goto 里最需要注意的。
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}0
简单例子
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}1
结果是BBBBB
,不会输出A
,直接就跳过去了。
注意事项
goto语句和标签之前不能有变量申明
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}2
这样会报错processcontrol\processcontrol.go:10:7: goto printB jumps over declaration of testP at processcontrol\processcontrol.go:13:6
常见用法
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}3
输出
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}4
defer延迟语句
延迟调用
defer 的用法很简单,只要在后面跟一个函数的调用,就能实现将这个 xxx
函数的调用延迟到当前函数执行完后(return后)再执行。
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}5
输出:
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}6
及时求值的变量快照
使用 defer 只是延时调用函数,此时传递给函数里的变量,不应该受到后续程序的影响。
如下:
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}7
闭包
这样写会产生闭包问题,str变量在外部。
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}8
输结果
funcTestIfElseHight(){ifa:=GetCondition("ONE");a==1{fmt.Println("TEST")}}funcGetCondition(conditionstring)int{ifcondition=="ONE"{return1}return0}9
str这个变量,在defer打印出来之后,还是输出的BBBBB
。
换种方式:
funcTestSwitchCase(){condition:="CASE1"switchcondition{case"CASE1":fmt.Println("CASE1PRINT")case"CASE2":fmt.Println("CASE2PRINT")default:fmt.Println("DEFAULTPRINT")}}0
输出
funcTestSwitchCase(){condition:="CASE1"switchcondition{case"CASE1":fmt.Println("CASE1PRINT")case"CASE2":fmt.Println("CASE2PRINT")default:fmt.Println("DEFAULTPRINT")}}1
执行顺序问题
defer执行语句像一个栈一样,先入后出,先写后执行
funcTestSwitchCase(){condition:="CASE1"switchcondition{case"CASE1":fmt.Println("CASE1PRINT")case"CASE2":fmt.Println("CASE2PRINT")default:fmt.Println("DEFAULTPRINT")}}2
结果:
funcTestSwitchCase(){condition:="CASE1"switchcondition{case"CASE1":fmt.Println("CASE1PRINT")case"CASE2":fmt.Println("CASE2PRINT")default:fmt.Println("DEFAULTPRINT")}}3