Go语言学习路

Golang流程控制

2021-07-30  本文已影响0人  TZX_0710

Golang流程控制

Golang当中的流程控制

  1. if

    if语句由一个布尔表达式后紧跟一个或多个语句组成

    Go变成语言种if语句语法如下

    1.可省略条件表达式括号
    2.持初始化语句,可定义代码块局部变量
    3.代码块左  括号必须在条件表达式尾部
    if 布尔条件表达式{
    //代码块
    }
    
  2. switch

    switch语句用于基于不同条件执行不同动作,每一个case分支都是唯一的,从上直下逐一测试,直到匹配为止,Golang switch 分支表达式可以是任意类型不限于常量。可省略break 默认自动终止

    switch var1 {
     case val1:
         ...
     case val2:
         ...
     default:
         ...
    }
    
  3. 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进行求值
  4. 循环语句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
     }
    }
    
    
  5. 循环语句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不能做的

  6. 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)
     }
    }
    
  7. 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
     }
    
  8. 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
     }
    
上一篇下一篇

猜你喜欢

热点阅读