golang 流程控制
目录
前言
- 不做文字的搬运工,多做灵感性记录
- 这是平时学习总结的地方,用做知识库
- 平时看到其他文章的相关知识,也会增加到这里
- 随着学习深入,会进行知识拆分和汇总,所以文章会随时更新
- 参考的文章过多、很杂很乱,所以参考会写不全,见谅
流程控制
主要是三大流程控制流程控制语句
1)顺序控制
2)分支控制
3)循环控制
1.顺序控制
程序从上到下逐行地执行,中间没有任何判断和跳转。
-
注意
-
Golang中定义变量时采用合法的前向引用。
就是说你使用变量就需要提前声明它
-
2.分支语句
1.形式
- 单分支
- 双分支
- 多分支
2.单分支控制 if
基本语法
if 条件表达式 {
执行代码块
}
条件表达式为true时,就会执行{}的代码,注意{}是必须有的,就算你值写一行代码
// golang支持在if中直接定义一个变量
if age := 20;age > 18{
...
}
3.双分支语句 if
if 条件表达式 {
执行代码块 1
}else{
执行代码块 2
}
// 注意
1.条件表达式为true时,就会执行代码块1,否则就执行代码块2,注意{}是必须有的
2.双分支只会执行其中的一个分支
4.多分支控制 if
if 条件表达式 {
执行代码块1
}else if 条件表达式{
执行代码块2
}else if 条件表达式{
执行代码块3
}else{
执行代码块 n
}
// 注意
else不是必须的,但多分支只能执行一个执行入口
5.嵌套分支
在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支,外面的分支结构称为外层分支。嵌套分支不宜过多,建议控制在3层内。
6.switch分支控制
- switch语句用于基于不同条件执行不同动作,每一个case分支都是唯一的,从上到下逐一测试,直到匹配为止。
- 匹配项后面也不需要再加break
switch 表达式{
case 表达式1,表达式2,...:
语句块1
case 表达式3,表达式4,...:
语句块2
default:
语句块3
}
// 注意
1.先执行switch的表达式得到值。然后执行case的语句,进行比较,遇到相等的,就比配到,执行对应的case的语句块,然后退出switch,如果没有匹配成功,就会执行default语句
2.case后的表达式可以有多个,用逗号隔开
3.switch 后面也可以不带表达式,直接跟上(:)类似 if - case 分支来使用
switch:{}
4.switch 后面也可以直接声明/定义一个变量,以分号结尾(不推荐)
switch grade:=90;{}
5.switch穿透-fallthough,
如果在case语句块后增加fallthrough,会继续执行下一个case,
var num int = 20
switch num{
case 10:
fmt.Print('ok')
fallthrough //默认只能穿透一层,执行case 30
case 30:
fmt.Print('1')
// case不需写break,默认情况下执行case语句以后,就跳出switch控制语句
break
default: // 不是必须的,
fmt.Print('2')
}
6.type-switch:
// 判断某个interface 变量中实际指向的变量类型
var x interface{}
var y = 10.0
x = y
switch i:=x.(type){
case nil:
fmt.Print('x的类型是:%T',i)
case int:
fmt.Print('x的类型是整型')
}
7.switch 和 if 区别
-
如果判断的具体数值不多,而且符合整数、浮点数、字符、字符串这几种类型。建议使用swtich语句,简洁高效。
-
其他情况:对区间判断和结果为bool类型的判断,使用if, if的使用范围更广。
3.循环结构
- golang中没有while和do..while的语法,需要通过for循环实现
1.for循环结构
for 循环变量初始化 ;循环条件 ; 循环变量迭代{
循环执行语句(语句)
}
// 注意省略情况
1. 省略初始化循环变量、循环变量迭代: //相当于while循环
for i > 10{}
循环变量初始化
说明:1.此for循环是一个无限循环
2.break就是来跳出for语句
2.全部省略 // 无限循环
1.保留分号
for ; ;{
循环执行语句
break
}
2.不保留分号
// 实现 while
// 实现 do - while
for{
循环执行语句
break
}
2.实现while 循环
for{
if 循环条件表达式{
break //跳出for循环
}
循环操作(语句)
循环变量迭代
}
3.实现 do - while
循环变量初始化
for{
循环操作(语句)
循环变量的迭代
if 循环条件表达式{
break //跳出for循环
}
}
1.先执行,再判断,因此至少执行一次
2.循环条件成立后,就会执行break,跳出for 循环,结束循环
4.构成
1.初始语句
开始循环执行的语句, 第一次循环前执行的语句,一般使用初始语句执行变量初始化,如果变量在此处被声明,其作用域将被局限在这个 for 的范围内。
初始语句可以被忽略,但是初始语句之后的分号必须要写,
2.条件表达式
控制是否循环的开关, 每次循环开始前都会计算条件表达式,
表达式为 true :则循环继续,
表达式为False :结束循环
表达式忽略 :后默认形成无限循环。
3.结束语句
在结束每次循环前执行的语句,如果循环被 break、goto、return、panic 等语句强制退出,结束语句不会被执行。
5.多重循环控制
- 一个循环放在另一个循环体内,就形成了嵌套循环,建议一般使用两层,最多不适用三层
- 实质就是内层循环的循环条件为false时,才会跳出内层循环,才结束外层的 当次 循环
- 外层循环m次,内层循环n次,则内层循环体需要执行 m * n次
- 编译后先易后难,将一个复杂的问题分解为简单的问题,
6.跳出循环
1. break
- 一般都是用来跳出
for
或switch
语句。在 Go 中也可以在select
语句中使用break
。 - 跳出 当前(最近) 的 for 循环或者switch语句
- 跳出标签
// break后面可以指定标签,跳出标签对应的for循环
// 为不带标签的break只能终止最内层(innermost)的循环,如果像终止外部的循环,就得用标签了:
lable 2:
for i := 0;i < 4; i++{
for j := 0;j < 4;j++{ //设置一个lable1
if j == 2{
break lable2 //跳出lable2下面对应的for循环
}
}
}
- 语句不能跨越函数边界。
// 跨越边界会报错 break is not in a loop, switch, or select
2. fallthrough
2.contine
-
跳出本次循环,执行下一次循环
-
可以通过标签指明要跳过的哪一层循环,调到标签对应的 for 循环处
here: for i:=0;i<4;i++{ for j:=1;j<4;j++{ if j==2{ continue here } fmt.Print("i=",i,"j=",j) } } /* i= 0 j= 1 i= 1 j= 1 i= 2 j= 1 i= 3 j= 1 */
3.goto
- 可以无条件跳到程序中指定的行,接着往下运行
- goto语句通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能。
- 不建议使用,以免造成程序流程的混乱,使理解和调试程序都产生困难
if n > 20{
goto lable2
}
lable2:
4.return
-
如果return是在普通的函数,则表示跳出当前所在的方法或函数,即不再执行函数中return后面代码,也可以理解成终止函数
-
如果return是在main函数,表示终止main函数,也就是说终止程序。
-
1、无返回类型
- return语句不能返回任何值。
-
2、有返回类型
-
返回值可以显示地写在return的后面,每个表达式必须是单值的
func simpleF() int { return 2 } func complexF1() (re float64, im float64) { return -7.0, -4.0 }
-
return语句中的表达式列表可以是对返回多只函数的调用
func complexF2() (re float64, im float64) { return complexF1() }
-
如果函数的返回类型参数指定了名字,则 return 可以返回空。这些返回类型参数就像本地变量一样。
// 所有的结果值在函数的开始时都被初始化为它们的零值 func complexF3() (re float64, im float64) { re = 7.0 im = 4.0 return // 没有参数的 return 语句返回各个返回变量的当前值。这种用法被称作“裸”返回。 } func (devnull) Write(p []byte) (n int, _ error) { n = len(p) return } func f(n int) (res int, err error) { if _, err := f(n-1); err != nil { return // invalid return statement: err is shadowed ,编译器不允许返回空?? } return } // 编译器不知道你具体会在哪里返回,这个要运行时才能确定,所以,你最外面没有返回,编译器就认为你错了,语法不通过 // 尽量不要使用 func test() error{} 这种哦最后不能裸返回,有点儿糟心
-