Golang流程控制
2021-07-30 本文已影响0人
TZX_0710
Golang流程控制
Golang当中的流程控制
if
if语句由一个布尔表达式后紧跟一个或多个语句组成
Go变成语言种if语句语法如下
1.可省略条件表达式括号 2.持初始化语句,可定义代码块局部变量 3.代码块左 括号必须在条件表达式尾部 if 布尔条件表达式{ //代码块 }
switch
switch语句用于基于不同条件执行不同动作,每一个case分支都是唯一的,从上直下逐一测试,直到匹配为止,Golang switch 分支表达式可以是
任意类型
不限于常量。可省略break 默认自动终止switch var1 { case val1: ... case val2: ... default: ... }
select语句
select语句类似于switch语句,但是select会随机执行一个可运行的case,如果没有case可运行,它将阻塞,直到由case可运行。select是Go的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接受。select随机执行一个可运行的case。如果没有case可运行。它将阻塞,一个默认的子句应该是可运行的。
select { case communication clause : statement(s); case communication clause : statement(s); /* 你可以定义任意数量的 case */ default : /* 可选 */ statement(s); }
- 每个case都必须是一个通信
- 所有cahnnel表达式都会被求值
- 所有被发送的表达式都会被求值
- 如果任意某个通信可以进行,它就执行;其他被忽略
- 如果有多个case都可以运行,select会随机公平的选出一个执行。其他不会
- 如果有default子句,则执行该语句
- 如果没有defaultt子句,select将阻塞,直到某个通信可以运行;Go不会重新对channle进行求值
循环语句for
for循环时一个循环控制结构,可以执行指定次数的循环。
for init;condition;post{} for condition{} for{} //init 初始化条件 //condition 条件表达式 //post赋值表达式 1.对表达式进行赋值 2. 判断赋值表达式是否满足condition条件 若其值为真,满足循环条件,进入循环体 func main() { for i := 0; i < 3; i++ { fmt.Println("第一种循环") } var k = 0 for k<3 { fmt.Println("第二种循环") k++ } for { fmt.Println("第三种循环") break } }
循环语句range
Golang的range类似迭代器操作,返回(索引,值)或(键,值)
for key,value:=rage map{ newMap[key]=value } //for循环的range可以对 slice、map、数组、字符串等进行迭代 //举例 type student struct { Name string Age int } func pase_student() { m := make(map[string]*student) stus := []student{ {Name: "zhou", Age: 24}, {Name: "li", Age: 23}, {Name: "wang", Age: 22}, } for _, stu := range stus { m[stu.Name] = &stu } } //map[li:0xc000098420 wang:0xc000098420 zhou:0xc000098420] //对于以上代码进行对map赋值最后发现vlaue的值结果都是一样的,原因如下: //使用 for range 语法的控制结构最终应该也会被golang的编译器转换成普通的 for 循环,所以for range实际上会被先转换成经典的for循环再真正执行,而正是这个转换过程常常会留坑。 //&v实际上是对循环内部同一个短变量的取址,因此res中存的其实都是同一个地址,这个地址中的值实际上是最后一次循环赋的值。 //因为for range在遍历值类型时,其中的stu变量是一个值的拷贝,当使用&获取指针时,实际上是获取到v这个临时变量的指针,而v变量在for range中只会创建一次,之后循环中会被一直重复使用,所以在m赋值的时候其实都是stu变量的指针,而&stu最终会指向student最后一个元素的值拷贝
1Value 2Value string index str[index] array/slice index array[index] map key m[] channel element for 和channel的使用场景比较:
for range 遍历array和slice 遍历array和slice 遍历key为整形递增的map 遍历key为整形递增的map 遍历string 遍历string 遍历channel 遍历key为string类型的map,同时获取key和value for range可以完成for可以做的事情,还可以完成for不能做的
Goto label
Goto时调整执行位置,与continue、break配合标签label的结果并不相同。Goto没有限制
func main() { var i = 10 if i > 1 { //跳转到AA标签进行执行 goto AA } //AA标签 标签名区分大小写、AA和aa是2个标签 AA: for i := 0; i < 11; i++ { fmt.Println(i) } }
break label
break label的跳转标签必须放在for循环前面,并且在break label跳出循环不再执行for循环里面的代码
Stop: for i := 0; i < 3; i++ { fmt.Println("打印====>" + strconv.Itoa(i)) if i == 1 { break Stop } fmt.Println("skip====>" + strconv.Itoa(i)) //打印====>0 //skip====>0 //打印====>1 }
continue label
continue label的作用跟break label都只能用于修饰循环。continue label跳出本次循环 还会继续下次循环
fmt.Println("=====================") ContinueLabel: for i := 0; i < 3; i++ { fmt.Println("打印====>" + strconv.Itoa(i)) if i == 1 { continue ContinueLabel } fmt.Println("skip====>" + strconv.Itoa(i)) //打印====>0 //skip====>0 //打印====>1 //打印====>2 //skip====>2 }