golang 流程控制

100018 · · 1005 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go语言的流程控制主要分为三大类:

1.聽条件判断
2.聽循环控制
3.聽无条件跳转

条件判断

Go语言的条件判断由if ... else if ... else 语句实现,条件表达式值必须是布尔类型,可省略圆括号,但是花括号不能省略且左花括号不能另起一行,比如:

if聽7%2聽==聽0聽{
聽聽聽聽fmt.Println("7聽is聽even")
}聽else聽{
聽聽聽聽fmt.Println("7聽is聽odd")
}聽聽聽聽
if聽8%4聽==聽0聽{聽聽聽//可以没有else只有if语句
聽聽聽聽fmt.Println("8聽is聽divisible聽by聽4")
}

Go语言比较特别的是在条件判读语句中支持初始化语句,允许定义局部变量,但是这个变量的作用域仅限于该条件逻辑块内,比如:

if聽num聽:=聽9;聽num聽<聽0聽{
聽聽聽聽fmt.Println(num,聽"is聽negative")
}聽else聽if聽num聽<聽10聽{
聽聽聽聽fmt.Println(num,聽"has聽1聽digit")
}聽else聽{
聽聽聽聽fmt.Println(num,聽"has聽multiple聽digits")
}

最典型的应用就是字典的查找:

if聽v,聽ok聽:=聽map1[key1];聽ok{
聽聽聽聽...
}

优化建议:

  1. 对于那些过于复杂的组合条件判断,建议独立出来封装成函数,将流程控制和实现细节分离,使你的代码更加模块化,提高可读性.

  2. 有些时需要写很多的if-else实现一些复杂的逻辑处理,这时代码看上去就很罗嗦很冗长,而且也不易于以后的维护,用switch...case来很好的解决这个问题.


switch...case

switch与if类似,也用于选择执行,执行的过程从上至下顺序匹配各个case,基本用法如下:

switch聽sExpr聽{聽聽聽聽
聽聽聽聽case聽expr1:
聽聽聽聽聽聽聽聽some聽instructions聽聽聽聽
聽聽聽聽case聽expr2:
聽聽聽聽聽聽聽聽some聽other聽instructions
聽聽聽聽case聽expr3:
聽聽聽聽聽聽聽聽some聽other聽instructions
聽聽聽聽default:
聽聽聽聽聽聽聽聽other聽code
}

switch中的表达式可以不是常量或字符串,甚至可以沒有表达式,若没有表达式则匹配true, 如同if-else if-else,与 其它编程语言的switch用法基本相同,不同的是在每个case中隐藏了break,不过也可以显示加入break。 当case匹配成功后,处理当前case的处理逻辑,正常情况下,处理完成后就跳出整个switch,但这不是绝对的, 可以使用fallthrough强迫程序执行后面的case; 如果没有任何case匹配成功,则执行default逻辑,比如:

免写break:

{
聽聽聽聽i聽:=聽2
聽聽聽聽switch聽i聽{聽聽聽聽聽聽聽聽聽聽聽聽聽聽//将i聽与case条件匹配
聽聽聽聽聽聽聽聽case聽1:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("one")聽聽//break没有实际意义,直接跳出switch
聽聽聽聽聽聽聽聽case聽2:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("two")聽聽
聽聽聽聽聽聽聽聽case聽3:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("three")
聽聽聽聽}
}

多表达式判断:

{聽聽聽聽
聽聽聽聽switch聽time.Now().Weekday()聽{
聽聽聽聽聽聽聽聽case聽time.Saturday,聽time.Sunday:聽//在同一个case中可以写多个表达式,它们之间是逻辑或的关系
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("it's聽the聽weekend")
聽聽聽聽聽聽聽聽default:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("it's聽a聽weekday")
聽聽聽聽}
}

无表达式:

{
聽聽聽聽t聽:=聽time.Now()聽聽聽
聽聽聽聽switch聽{聽聽聽聽聽聽聽聽聽聽聽聽//没有表达式,相当于if-else
聽聽聽聽聽聽聽聽case聽t.Hour()聽<聽12:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("it's聽before聽noon")聽聽聽聽
聽聽聽聽聽聽聽聽default:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("it's聽after聽noon")
聽聽聽聽}
}

fallthrough:

{
聽聽聽聽i聽:=聽2
聽聽聽聽switch聽i聽{聽聽聽聽
聽聽聽聽聽聽聽聽case聽1:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("one")聽聽聽聽
聽聽聽聽聽聽聽聽case聽2:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("two")
聽聽聽聽聽聽聽聽聽聽聽聽fallthrough聽聽聽聽//使用fallthrough强迫程序执行后面的case
聽聽聽聽聽聽聽聽case聽3:
聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println("three")
聽聽聽聽}
}

循环控制

for是Go语言中仅有的一种循环语句,下面是常见的三种用法:

for聽j聽:=聽7;聽j聽<=聽9;聽j++聽{聽//典型的用法聽initial/condition/after
聽聽聽聽fmt.Println(j)
}

i聽:=聽1
for聽i聽<=聽3聽{聽聽聽聽聽聽聽聽聽聽聽聽//类似while(i聽<=聽3){}聽或for聽;聽i<=3聽;;{}
聽聽聽聽fmt.Println(i)
聽聽聽聽i聽=聽i聽+聽1
}

for聽{聽聽聽聽//类似while(true){}聽或for聽true聽{}
聽聽聽聽fmt.Println("loop")聽聽聽
聽聽聽聽...聽聽聽聽聽
聽聽聽聽break
}

PS:初始化语句只会被执行一次,并且初始化表达式支持函数调用或定义局部变量

在日常开发中for经常与range搭配,for...range被用来遍历字符串、数组、切片、字典和通道等,返回索引和键值数据,比如:

{聽聽聽聽for聽i,聽c聽:=聽range聽"go"聽{聽聽聽聽聽聽聽聽聽聽聽聽//range聽string
聽聽聽聽聽聽聽聽fmt.Println(i,聽c)
聽聽聽聽}

聽聽聽聽nums聽:=聽[]int{2,聽3,聽4}聽聽聽聽
聽聽聽聽for聽i,聽num聽:=聽range聽nums聽{聽聽聽聽聽聽聽聽聽聽//range聽array/slice
聽聽聽聽聽聽聽聽fmt.Println(i,聽":",聽num)
聽聽聽聽}

聽聽聽聽kvs聽:=聽map[string]string{"a":聽"apple",聽"b":聽"banana"}聽聽聽聽
聽聽聽聽for聽k,聽v聽:=聽range聽kvs聽{聽聽聽聽聽聽聽聽聽//range聽map
聽聽聽聽聽聽聽聽fmt.Printf("%s聽->聽%s\n",聽k,聽v)
聽聽聽聽}

聽聽聽聽chs聽:=聽make(chan聽int,10)聽聽聽聽//range聽channel
聽聽聽聽chs聽<-聽1
聽聽聽聽chs聽<-聽2
聽聽聽聽close(chs)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽for聽v聽:=聽range聽chs聽{
聽聽聽聽聽聽聽聽fmt.Println(v)
聽聽聽聽}
}

简单归纳如下:

data typefirst valuesecond value
stringindexs[index]
array/sliceindexv[index]
mapkeyvalue
channelelement


无条件跳转

Go语言有三种跳转类型,分别是 continue, break, goto

continue:仅用于for循环内部聽,终止本次循环,立即进入下一轮循环
break:用于for循环,聽switch,select语句,终止整个语句块的执行
goto:定点跳转,但不能跳转到其他函数或内层代码块内

看下面的例子:

func聽over(){
聽聽聽聽over:聽聽聽//label聽over聽defined聽and聽not聽used
聽聽聽聽println("call聽over")
}
func聽main(){
聽聽聽聽rand.Seed(time.Now().UnixNano())聽聽聽聽
聽聽聽聽for聽{
聽聽聽聽聽聽聽聽loop:
聽聽聽聽聽聽聽聽x聽:=聽rand.Intn(100)聽聽聽聽聽//获取一个100以内的随机数
聽聽聽聽聽聽聽聽if聽x聽%聽2聽==聽0{聽聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽聽continue聽聽聽聽聽聽聽聽//终止本次循环,立即进入下一轮循环
聽聽聽聽聽聽聽聽}聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽if聽x聽>聽50{聽聽聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽聽break聽聽聽聽聽聽聽聽聽聽聽//终止整个语句块的执行
聽聽聽聽聽聽聽聽}聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽println(x)
聽聽聽聽}聽聽聽聽
聽聽聽聽goto聽over聽聽聽聽聽聽聽//label聽over聽not聽defined
聽聽聽聽goto聽loop聽聽聽聽聽聽聽//goto聽loop聽jumps聽into聽block聽starting}

goto 的习惯用法:

{
聽聽聽聽f,聽err聽:=聽os.Open("/tmp/dat")聽聽聽聽
聽聽聽聽if聽err聽!=聽nil{
聽聽聽聽聽聽聽聽....
聽聽聽聽聽聽聽聽聽goto聽exit
聽聽聽聽}
聽聽聽聽...
聽聽聽聽n1,聽err聽:=聽f.Read(b1)
聽聽聽聽if聽err聽!=聽nil{聽
聽聽聽聽聽聽聽聽goto聽end
聽聽聽聽}
聽聽聽聽...

end:聽聽聽聽
聽聽聽聽println("clear聽resource聽and聽exit")
聽聽聽聽f.close()
exit:聽聽聽聽
聽聽聽聽return
}

借鉴: 雨痕<GO学习笔记>

讨论学习: 675020908

本文出自 “博学于文,约之于礼” 博客,转载请与作者联系!


有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:100018

查看原文:golang 流程控制

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1005 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传