golang 流程控制
Go语言的流程控制主要分为三大类:
1.条件判断2.循环控制3.无条件跳转条件判断
Go语言的条件判断由if ... else if ... else 语句实现,条件表达式值必须是布尔类型,可省略圆括号,但是花括号不能省略且左花括号不能另起一行,比如:
if7%2==0{fmt.Println("7iseven")}else{fmt.Println("7isodd")}if8%4==0{//可以没有else只有if语句fmt.Println("8isdivisibleby4")}
Go语言比较特别的是在条件判读语句中支持初始化语句,允许定义局部变量,但是这个变量的作用域仅限于该条件逻辑块内,比如:
ifnum:=9;num<0{fmt.Println(num,"isnegative")}elseifnum<10{fmt.Println(num,"has1digit")}else{fmt.Println(num,"hasmultipledigits")}
最典型的应用就是字典的查找:
ifv,ok:=map1[key1];ok{...}
优化建议:
对于那些过于复杂的组合条件判断,建议独立出来封装成函数,将流程控制和实现细节分离,使你的代码更加模块化,提高可读性.
有些时需要写很多的if-else实现一些复杂的逻辑处理,这时代码看上去就很罗嗦很冗长,而且也不易于以后的维护,用switch...case来很好的解决这个问题.
switch...case
switch与if类似,也用于选择执行,执行的过程从上至下顺序匹配各个case,基本用法如下:
switchsExpr{caseexpr1:someinstructionscaseexpr2:someotherinstructionscaseexpr3:someotherinstructionsdefault:othercode}
switch中的表达式可以不是常量或字符串,甚至可以沒有表达式,若没有表达式则匹配true, 如同if-else if-else,与 其它编程语言的switch用法基本相同,不同的是在每个case中隐藏了break,不过也可以显示加入break。 当case匹配成功后,处理当前case的处理逻辑,正常情况下,处理完成后就跳出整个switch,但这不是绝对的, 可以使用fallthrough强迫程序执行后面的case; 如果没有任何case匹配成功,则执行default逻辑,比如:
免写break:
{i:=2switchi{//将i与case条件匹配case1:fmt.Println("one")//break没有实际意义,直接跳出switchcase2:fmt.Println("two")case3:fmt.Println("three")}}
多表达式判断:
{switchtime.Now().Weekday(){casetime.Saturday,time.Sunday://在同一个case中可以写多个表达式,它们之间是逻辑或的关系fmt.Println("it'stheweekend")default:fmt.Println("it'saweekday")}}
无表达式:
{t:=time.Now()switch{//没有表达式,相当于if-elsecaset.Hour()<12:fmt.Println("it'sbeforenoon")default:fmt.Println("it'safternoon")}}
fallthrough:
{i:=2switchi{case1:fmt.Println("one")case2:fmt.Println("two")fallthrough//使用fallthrough强迫程序执行后面的casecase3:fmt.Println("three")}}循环控制
for是Go语言中仅有的一种循环语句,下面是常见的三种用法:
forj:=7;j<=9;j++{//典型的用法initial/condition/afterfmt.Println(j)}i:=1fori<=3{//类似while(i<=3){}或for;i<=3;;{}fmt.Println(i)i=i+1}for{//类似while(true){}或fortrue{}fmt.Println("loop")...break}
PS:初始化语句只会被执行一次,并且初始化表达式支持函数调用或定义局部变量
在日常开发中for经常与range搭配,for...range被用来遍历字符串、数组、切片、字典和通道等,返回索引和键值数据,比如:
{fori,c:=range"go"{//rangestringfmt.Println(i,c)}nums:=[]int{2,3,4}fori,num:=rangenums{//rangearray/slicefmt.Println(i,":",num)}kvs:=map[string]string{"a":"apple","b":"banana"}fork,v:=rangekvs{//rangemapfmt.Printf("%s->%s\n",k,v)}chs:=make(chanint,10)//rangechannelchs<-1chs<-2close(chs)forv:=rangechs{fmt.Println(v)}}
简单归纳如下:
Go语言有三种跳转类型,分别是 continue, break, goto
continue:仅用于for循环内部,终止本次循环,立即进入下一轮循环break:用于for循环,switch,select语句,终止整个语句块的执行goto:定点跳转,但不能跳转到其他函数或内层代码块内
看下面的例子:
funcover(){over://labeloverdefinedandnotusedprintln("callover")}funcmain(){rand.Seed(time.Now().UnixNano())for{loop:x:=rand.Intn(100)//获取一个100以内的随机数ifx%2==0{continue//终止本次循环,立即进入下一轮循环}ifx>50{break//终止整个语句块的执行}println(x)}gotoover//labelovernotdefinedgotoloop//gotoloopjumpsintoblockstarting}
goto 的习惯用法:
{f,err:=os.Open("/tmp/dat")iferr!=nil{....gotoexit}...n1,err:=f.Read(b1)iferr!=nil{gotoend}...end:println("clearresourceandexit")f.close()exit:return}
借鉴: 雨痕<GO学习笔记>
讨论学习: 675020908
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。