Golang中的流程控制有哪些及怎么实现
这篇文章主要讲解了“Golang中的流程控制有哪些及怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang中的流程控制有哪些及怎么实现”吧!
Go语言基础之流程控制主要包括以下内容:
条件语句if
条件语句switch
条件语句select
循环语句for
循环语句range
循环控制Goto、Break、Continue
1. 条件语句if
Go语言中if
条件判断的格式如下:
if表达式1{分支1}elseif表达式2{分支2}else{分支3}
前端的同学想必对js相对熟悉,相对于js来说,go表达式去掉了括号()
,但同时给了一些约束,与if
匹配的左括号{
必须与if和表达式
放在同一行,{
放在其他位置会触发编译错误。 同理,与else
匹配的{
也必须与else
写在同一行,else
也必须与上一个if
或else if
右边的大括号在同一行。
x:=0//ifx>10//Error:missingconditioninifstatement//{//}ifn:="abc";x>0{//初始化语句未必就是定义变量,如println("init")也是可以的。println(n[2])}elseifx<0{//注意elseif和else左大括号位置。println(n[1])}else{println(n[0])}*不支持三元操作符(三目运算符)"a>b?a:b"。packagemainimport"fmt"funcmain(){/*定义局部变量*/varaint=10/*使用if语句判断布尔表达式*/ifa<20{/*如果条件为true则执行以下语句*/fmt.Printf("a小于20\n")}fmt.Printf("a的值为:%d\n",a)}以上代码执行结果为:a小于20a的值为:10
2. 条件语句switch
switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上直下逐一测试,直到匹配为止。 Golang switch 分支表达式可以是任意类型,不限于常量。可省略 break,默认自动终止。
packagemainimport"fmt"funcmain(){/*定义局部变量*/vargradestring="B"varmarksint=90switchmarks{case90:grade="A"case80:grade="B"case50,60,70:grade="C"default:grade="D"}switch{casegrade=="A":fmt.Printf("优秀!\n")casegrade=="B",grade=="C":fmt.Printf("良好\n")casegrade=="D":fmt.Printf("及格\n")casegrade=="F":fmt.Printf("不及格\n")default:fmt.Printf("差\n")}fmt.Printf("你的等级是%s\n",grade)}以上代码执行结果为:优秀!你的等级是A
3. 条件语句select
select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。
select 是Go中的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。 select 随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的。
以下描述了 select 语句的语法:
select可以监听channel的数据流动每个case都必须是一个通信所有channel表达式都会被求值所有被发送的表达式都会被求值如果任意某个通信可以进行,它就执行;其他被忽略。如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。否则:如果有default子句,则执行该语句。如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。
packagemainimport"fmt"funcmain(){varc1,c2,c3chanintvari1,i2intselect{casei1=<-c1:fmt.Printf("received",i1,"fromc1\n")casec2<-i2:fmt.Printf("sent",i2,"toc2\n")casei3,ok:=(<-c3)://sameas:i3,ok:=<-c3ifok{fmt.Printf("received",i3,"fromc3\n")}else{fmt.Printf("c3isclosed\n")}default:fmt.Printf("no munication\n")}}以上代码执行结果为:no munication
select的用法与switch语法非常类似,由select开始的一个新的选择块,每个选择条件由case语句来描述
与switch语句可以选择任何使用相等比较的条件相比,select有比较多的限制,其中最大的一条限制就是每个case语句里必须是一个IO操作
在一个select语句中,Go会按顺序从头到尾评估每一个发送和接收的语句。select{//不停的在这里检测case<-chanl://检测有没有数据可以读//如果chanl成功读取到数据,则进行该case处理语句casechan2<-1://检测有没有可以写//如果成功向chan2写入数据,则进行该case处理语句//假如没有default,那么在以上两个条件都不成立的情况下,就会在此阻塞//一般default会不写在里面,select中的default子句总是可运行的,因为会很消耗CPU资源default://如果以上都没有符合条件,那么则进行default处理流程}
如果其中的任意一个语句可以继续执行(即没有被阻塞),那么就从那些可以执行的语句中任意选择一条来使用。 如果没有任意一条语句可以执行(即所有的通道都被阻塞),那么有两种可能的情况: ①如果给出了default语句,那么就会执行default的流程,同时程序的执行会从select语句后的语句中恢复。 ②如果没有default语句,那么select语句将被阻塞,直到至少有一个case可以进行下去。
典型用法-超时判断
//比如在下面的场景中,使用全局resChan来接受response,如果时间超过3S,resChan中还没有数据返回,则第二条case将执行varresChan=make(chanint)//dorequestfunctest(){select{casedata:=<-resChan:doData(data)case<-time.After(time.Second*3):fmt.Println("requesttimeout")}}funcdoData(dataint){//...}
4. 循环语句for
和if一样,相对于js,go语言的for循环也去掉了括号(),其他并没有太大的区别。
packagemainimport"fmt"funcmain(){varbint=15varaintnumbers:=[6]int{1,2,3,5}/*for循环*/fora:=0;a<10;a++{fmt.Printf("a的值为:%d\n",a)}fora<b{a++fmt.Printf("a的值为:%d\n",a)}fori,x:=rangenumbers{fmt.Printf("第%d位x的值=%d\n",i,x)}}以上实例运行输出结果为:a的值为:0a的值为:1a的值为:2a的值为:3a的值为:4a的值为:5a的值为:6a的值为:7a的值为:8a的值为:9a的值为:1a的值为:2a的值为:3a的值为:4a的值为:5a的值为:6a的值为:7a的值为:8a的值为:9a的值为:10a的值为:11a的值为:12a的值为:13a的值为:14a的值为:15第0位x的值=1第1位x的值=2第2位x的值=3第3位x的值=5第4位x的值=0第5位x的值=0
5. 循环语句range
Golang range类似迭代器操作,返回 (索引, 值) 或 (键, 值)。
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
登录后复制 for 和 for range有什么区别?forkey,value:=rangeoldMap{newMap[key]=value}
packagemainfuncmain(){s:="abc"//忽略2ndvalue,支持string/array/slice/map。fori:=ranges{println(s[i])}//忽略index。for_,c:=ranges{println(c)}//忽略全部返回值,仅迭代。forranges{}m:=map[string]int{"a":1,"b":2}//返回(key,value)。fork,v:=rangem{println(k,v)}}输出结果:979899979899a1b2
主要是使用场景不同
for可以遍历array和slice,遍历key为整型递增的map,遍历string
for range可以完成所有for可以做的事情,却能做到for不能做的,包括遍历key为string类型的map并同时获取key和value,遍历channel
6. 循环控制Goto、Break、Continue
循环控制语句
循环控制语句可以控制循环体内语句的执行过程。
GO 语言支持以下几种循环控制语句:
Goto、Break、Continue
1.三个语句都可以配合标签(label)使用2.标签名区分大小写,定以后若不使用会造成编译错误3.continue、break配合标签(label)可用于多层循环跳出4.goto是调整执行位置,与continue、break配合标签(label)的结果并不相同
break(跳出循环)
:continue(继续下次循环)break
语句可以结束for
、switch
和select
的代码块。break
语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的for
、switch
和 select
的代码块上。
continue(继续下次循环)
:continue
语句可以结束当前循环,开始下一次的循环迭代过程,仅限在for
循环内使用。在 continue
语句后添加标签时,表示开始标签对应的循环
goto
语句通过标签
进行代码间的无条件跳转。goto
语句可以在快速跳出循环、避免重复退出上有一定的帮助。Go语言中使用goto
语句能简化一些代码的实现过程。 例如双层嵌套的for循环要退出时:
使用funcgotoDemo1(){varbreakFlagboolfori:=0;i<10;i++{forj:=0;j<10;j++{ifj==2{//设置退出标签breakFlag=truebreak}fmt.Printf("%v-%v\n",i,j)}//外层for循环判断ifbreakFlag{break}}}
goto
语句能简化代码:funcgotoDemo2(){fori:=0;i<10;i++{forj:=0;j<10;j++{ifj==2{//设置退出标签gotobreakTag}fmt.Printf("%v-%v\n",i,j)}}return//标签breakTag:fmt.Println("结束for循环")}
感谢各位的阅读,以上就是“Golang中的流程控制有哪些及怎么实现”的内容了,经过本文的学习后,相信大家对Golang中的流程控制有哪些及怎么实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是主机评测网,小编将为大家推送更多相关知识点的文章,欢迎关注!