zoukankan      html  css  js  c++  java
  • Go语言--第4章 流程控制

    第4章 流程控制 

    主要内容

    4.1 条件判断--if

    Go语言规定与if匹配的左括号“{” 必须与if 和表达式放在同一行,如果尝试将“{”放在其他位置,将会触发编译错误

    与else 匹配的 “{” 也必须与else 在同一行

    else也必须与上-个if 或else if 的右边的大括号在一行

    格式:

    if 表达式1 {
        分支1
    } else if 表达式2 {
        分支2
    } else {
        分支3
    }
    // > 10

    特殊写法

    if 还有特殊的写法,可以在if表达式之前添加一个执行语句,再根据变量值进行判断,如:

      if err := Connect(); err != nil {
        fmt.Println(err)
        return
      }

    Connect() 为假设的函数,err := Connect() 可以视为一个表达式

    4.2 构建循环--for

    Go语言中所有循环类型均可以使用for关键字完成

    for 初始语句;条件表达式; 结束语句 {
    循环体代码
    }

    for 循环可以通过break,goto,return,panic语句强制退出循环

    4.2.1 for中初始语句--开始执行的语句

    初始语句可以被忽略,但是初始语句之后的分号必须要写

     step := 2
      for ; step > 0; step-- {
        fmt.Println(step)
      }
      // 2
      // 1
    

      

    4.2.2 for中条件表达式--控制是否循环的开关

    条件表达式也可以被忽略,忽略默认为无限循环

    1. 结束循环时带可执行语句的无限循环

      var i int
      for ; ; i++ {
        if i > 10 {
          fmt.Println("i > 10")
          break;
        }
      }
      // i > 10
    

      

    1. 无限循环

     for {
        if i > 10 {
          fmt.Println("i > 10")
          break
        }
        i++
      }
        // i > 10
    

      

    4.2.3 for中结束语句--每次循环结束时执行的语句

    在结束每次循环前执行的语句,被break 、goto、return、panic等语句强制推出

    示例:

    ​
      // 遍历九九乘法表
      for x:=1; x < 10; x++ {
        for y :=1; y <= x; y++ {
          sum := x * y
          fmt.Printf("%d * %d = %d ", x, y, sum )
        } 
        fmt.Printf("
    ")
      }
    ​
    结果
    
    1 * 1 = 1
    
    2 * 1 = 2 2 * 2 = 4
    
    3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
    
    4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16
    
    5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25
    
    6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36
    
    7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49
    
    8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64
    
    9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81
    

      

    4.4 键值循环(for range)-- 直接获得对象的索引和数据

    Go语言可以使用for range遍历、数据、切片、字符串、map及通道(channel)

    规律:

    • 数组、切片、字符串返回索引值

    • map返回键和值

    • 通道(channel)只返回通道内的值

    4.4.1 遍历数组、切片--获得索引和元素

    for key, value := range []int{1,2,3,4} {
        fmt.Printf("key: %d, value: %d
    ", key, value )
    }
    ​
    //key: 0, value: 1
    //key: 1, value: 2
    //key: 2, value: 3
    //key: 3, value: 4
    ​

    4.4.2 遍历字符串--获得字符

    for key, value := range "abcdef" {
        fmt.Printf("key: %d, value: 0x%x
    ", key, value )
    }
    ​
    //key: 0, value: 0x61
    //key: 1, value: 0x62
    //key: 2, value: 0x63
    //key: 3, value: 0x64
    //key: 4, value: 0x65
    //key: 5, value: 0x66
    

    4.4.3 遍历字典map--获得键和值

    m := map[int]string{
        1 : "one",
        2 : "two",
        3 : "three",
      }   
    for key,value := range m {
        fmt.Printf("key: %d, value: %s
    ", key, value )
    }
    // key: 1, value: one
    // key: 2, value: two
    // key: 3, value: three
    

      

    4.4.3 遍历通道channel -- 接受通道数据


     c := make(chan int)
      // 启动一个goroutine,往通道中推送数据1、2、3,然后关闭通道
      go func() {
        c <- 1
        c <- 2
        c <- 3
        close(c)
      }()
    ​
      for v := range c {
        fmt.Println(v)
      }
      
      // 1
      // 2
      // 3
    

      

    4.4.5 遍历中只选择需要的变量

    不需要获得的key或value,可以用下划线“-”代替,即匿名变量

    匿名变量,可理解为占位符,本身不会进行空间分配,不会占用变量的名字


    for _, value := range []int{1,2,3,4} {
        fmt.Printf("value: %d
    ",  value )
    }
    ​
    // value: 1
    // value: 2
    // value: 3
    // value: 4
    

     

    4.4.6 for总结

    for 功能:

    1. Go语言for包含初始条件,条件表达式、结束语句,这3个均可省略

    2. for range 支持数组、切片、字符串、map、通道遍历

    3. 可使用匿名变量获取只需要的变量

    4.5 分支选择(switch) -- 拥有多个条件分支的判断

    4.5.1 基本写法

    switch中每个case与case间是独立的代码块,不需要通过break语句跳出当前case代码块以避免执行到下一行

    Go语言规定每一个switch只能有一个default分支

      var a = "hello"
      switch a {
      case "hello":
        fmt.Println(1)
      case "world":
        fmt.Println(2)
      default:
        fmt.Println(0)
      }
    

      

    分支常见情况:

    1. 一分支多值

    ​
    switch a {
    case "hello", "world" :
    fmt.Println("Hi")
    }
    ​ 
    1. 分支表达式

    ​
    var r int = 11
    var s int = 5
    switch {
        case r > 10 && r <20:
        fmt.Println(r)
        case s > 2 && s <10:
        fmt.Println(s)
    }
    // 11
    

      

    如果只有一个变量判断的时候,switch后面可以不用添加变量r

    4.5.2 跨越case的fallthrough -- 兼容c语言的case设计

    fallthrough关键字用来实现case分支间的执行,应为go语言的case的是独立的代码块

      str := "hello"
      switch {
      case str == "hello":
        fmt.Println("hello")
        fallthrough
      case str != "world":
        fmt.Println("world")
      }
      // hello
      // world
    

      

    4.6 跳转到指定代码标签(goto)

    goto语句通过标签进行代码间的无条件跳转,可以快速跳出循环避免重复退出上有一定帮助

    4.6.1 使用goto退出多层循环

    原代码:

    packeage main
    import ("fmt")
    func main() {
        var breakAgain bool
        for  x := 0; x < 10; x++ {
            for y := 0; y <10; y++ {
                if y == 2 {
                    breakAgain = true
                   break
                }
            }
            if breakAgain {
              break
            }
      }
      fmt.Println("done") 
    }
    

     

    使用goto语句进行优化:

    使用goto语句后,无须额外的变量就可以进行快速退出所有的循环

    packeage main
    import ("fmt")
    func main() {
      for  x := 0; x < 10; x++ {
        for y := 0; y <10; y++ {
          if y == 2 {
            // 跳转到标签
            goto breakHere
          }
        }
    ​
      }
      // 手动返回,避免执行进入标签
      return
    ​
      // 标签
      breakHere:
        fmt.Println("done")
    }
    

      

    4.6.2 统一错误处理

    err := firstCheckError()
    if err != nil {
      goto onExit
    }
    ​
    err = secondCheckError()
    if err != nil {
      goto onExit
    }
    ​
    fmt.Println("done")
    return
    ​
    onExit:
      fmt.Println(err)
    

      

    4.7 跳出指定循环(break)

    break语句可以跳出for 、switch 和select代码块

    break语句后面添加标签,表示退出某个标签对应的代码块,标签必须定义在对应的for、switch和select的代码块上

    packeage main
    import ("fmt")
    func main() {
    ​
      loop:
        for i:=1; i<=3; i++ {
          for j := 0; j<5;j++ {
            switch j {
            case 2:
              fmt.Println(i,j)
                        // 退出 loop标签下的这个双循坏代码
              break loop 
            case 3:
              fmt.Println(i,j)
              break loop
            }
          }
        }
    }
     
    

      

    4.8 跳出当前循坏(continue)

    continue语句结束当前循坏,开始下一个循环,仅限于for循环内使用

    continue语句后面添加标签时,表示开始标签对应的循环

    packeage main
    import ("fmt")
    func main() {
    ​
      loop:
        for i:=0; i<=3; i++ {
          for j := 0; j<5;j++ {
            switch j {
            case 2:
              fmt.Println(i,j)
              continue loop
            } 
          }
        }
      
        // 0 2
        // 1 2
        // 2 2
        // 3 2
    }
        
    

      

     

     
  • 相关阅读:
    2018.11.7 PION 模拟赛
    洛谷 P1074 靶形数独
    洛谷 P2831 愤怒的小鸟
    2018.11.6 PION 模拟赛
    洛谷 P1034 矩形覆盖
    博客使用指南
    TERADATA SQL学习随笔<一>
    补发:用Meal Prep+模块化饮食来减肥之实操
    [从产品角度学excel 04]-单元格的“衣服”
    [从产品角度学EXCEL 03]-单元格的秘密
  • 原文地址:https://www.cnblogs.com/smallyi/p/11870309.html
Copyright © 2011-2022 走看看