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循环时一个循环控制结构,可以执行指定次数的循环。
```go for init;condition;post{} for condition{} for{} //init 初始化条件 //condition 条件表达式 //post赋值表达式 1.对表达式进行赋值
- 判断赋值表达式是否满足condition条件 若其值为真,满足循环条件,进入循环体
func main() { for i := 0; i < 3; i++ { fmt.Println(“第一种循环”) } var k = 0 for k<3 { fmt.Println(“第二种循环”) k++ } for { fmt.Println(“第三种循环”) break } }
> 5.循环语句range> Golang的range类似迭代器操作,返回(索引,值)或(键,值)> ```gofor key,value:=rage map{newMap[key]=value}//for循环的range可以对 slice、map、数组、字符串等进行迭代//举例type student struct {Name stringAge 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 = 10if 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}
