Go基础:流程控制-if、switch、select、for

简介: Go基础:流程控制-if、switch、select、for

 目录

条件语句if

条件语句switch

Type Switch

条件语句select

select 语句的语法:

select 典型用法

1.超时判断

2.退出

3.判断channel是否阻塞

循环语句for


条件语句if

20200219211752846.png

条件语句ifimage.gif

   • 可省略条件表达式括号。

   • 持初始化语句,可定义代码块局部变量。

   • 代码块左括号必须在条件表达式尾部

*不支持三元操作符(三目运算符) "a > b ? a : b"。

条件语句switch

20200219212740993.png

条件语句switchimage.gif

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

    20200219213142287.png

    条件语句switchimage.gif

    类型不被局限于常量或整数,但必须是相同的类型;或者最终结果为相同类型的表达式。

    您可以同时测试多个可能符合条件的值,使用逗号分割它们,例如:case val1, val2, val3。

    switch marks {
          case 90: grade = "A"
          case 80: grade = "B"
          case 50,60,70 : grade = "C"
          default: grade = "D"  
       }

    image.gif

    Type Switch

    switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。

    Type Switch 语法格式如下:

    switch x.(type){
        case type:
           statement(s)      
        case type:
           statement(s)
        /* 你可以定义任意个数的case */
        default: /* 可选 */
           statement(s)
    }

    image.gif

    实例:

    package main
    import "fmt"
    func main() {
        var x interface{}
        //写法一:
        switch i := x.(type) { // 带初始化语句
        case nil:
            fmt.Printf(" x 的类型 :%T\r\n", i)
        case int:
            fmt.Printf("x 是 int 型")
        case float64:
            fmt.Printf("x 是 float64 型")
        case func(int) float64:
            fmt.Printf("x 是 func(int) 型")
        case bool, string:
            fmt.Printf("x 是 bool 或 string 型")
        default:
            fmt.Printf("未知型")
        }
        //写法二
        var j = 0
        switch j {
        case 0:
        case 1:
            fmt.Println("1")
        case 2:
            fmt.Println("2")
        default:
            fmt.Println("def")
        }
        //写法三
        var k = 0
        switch k {
        case 0:
            println("fallthrough")
            fallthrough
            /*
                Go的switch非常灵活,表达式不必是常量或整数,执行的过程从上至下,直到找到匹配项;
                而如果switch没有表达式,它会匹配true。
                Go里面switch默认相当于每个case最后带有break,
                匹配成功后不会自动向下执行其他case,而是跳出整个switch,
                但是可以使用fallthrough强制执行后面的case代码。
            */
        case 1:
            fmt.Println("1")
        case 2:
            fmt.Println("2")
        default:
            fmt.Println("def")
        }
        //写法三
        var m = 0
        switch m {
        case 0, 1:
            fmt.Println("1")
        case 2:
            fmt.Println("2")
        default:
            fmt.Println("def")
        }
        //写法四
        var n = 0
        switch { //省略条件表达式,可当 if...else if...else
        case n > 0 && n < 10:
            fmt.Println("i > 0 and i < 10")
        case n > 10 && n < 20:
            fmt.Println("i > 10 and i < 20")
        default:
            fmt.Println("def")
        }
    }

    image.gif

    以上代码执行结果为:

    x 的类型 :<nil>
        fallthrough
        1
        1
        def

    image.gif

    条件语句select

    select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。

    如果没有case可运行,它将阻塞,直到有case可运行。

    select 语句的语法:

    select {
        case communication clause  :
           statement(s);      
        case communication clause  :
           statement(s);
        /* 你可以定义任意数量的 case */
        default : /* 可选 */
           statement(s);
    }

    image.gif

    以下描述了 select 语句的语法:

      •    每个case都必须是一个通信
      •    所有channel表达式都会被求值
      •    所有被发送的表达式都会被求值
      •    如果任意某个通信可以进行,它就执行;其他被忽略。
      •    如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。
      •    否则:
        •    如果有default子句,则执行该语句。
        •    如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。

          select 典型用法

          1.超时判断

          //比如在下面的场景中,使用全局resChan来接受response,如果时间超过3S,resChan中还没有数据返回,则第二条case将执行
          var resChan = make(chan int)
          // do request
          func test() {
              select {
              case data := <-resChan:
                  doData(data)
              case <-time.After(time.Second * 3):
                  fmt.Println("request time out")
              }
          }
          func doData(data int) {
              //...
          }

          image.gif

          2.退出

          //主线程(协程)中如下:
          var shouldQuit=make(chan struct{})
          fun main(){
              {
                  //loop
              }
              //...out of the loop
              select {
                  case <-c.shouldQuit:
                      cleanUp()
                      return
                  default:
                  }
              //...
          }
          //再另外一个协程中,如果运行遇到非法操作或不可处理的错误,就向shouldQuit发送数据通知程序停止运行
          close(shouldQuit)

          image.gif

          3.判断channel是否阻塞

          //在某些情况下是存在不希望channel缓存满了的需求的,可以用如下方法判断
          ch := make (chan int, 5)
          //...
          data:=0
          select {
          case ch <- data:
          default:
              //做相应操作,比如丢弃data。视需求而定
          }

          image.gif

          循环语句for

          20200219220152850.png

          循环语句forimage.gif

          Go语言的For循环有3中形式,只有其中的一种使用分号。

            •    for init; condition; post { }
            •    for condition { }
            •    for { }

               init: 一般为赋值表达式,给控制变量赋初值;

               condition: 关系表达式或逻辑表达式,循环控制条件;

               post: 一般为赋值表达式,给控制变量增量或减量。

              •    for语句执行过程如下:
                •    ①先对表达式 init 赋初值;
                •    ②判别赋值表达式 init 是否满足给定 condition 条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句。
                  s := "abc"
                  for i, n := 0, len(s); i < n; i++ { // 常见的 for 循环,支持初始化语句。
                      println(s[i])
                  }
                  n := len(s)
                  for n > 0 {                // 替代 while (n > 0) {}
                      println(s[n])        // 替代 for (; n > 0;) {}
                      n-- 
                  }
                  for {                    // 替代 while (true) {}
                      println(s)            // 替代 for (;;) {}
                  }

                  image.gif

                  不要期望编译器能理解你的想法,在初始化语句中计算出全部结果是个好主意。

                  package main
                  func length(s string) int {
                      println("call length.")
                      return len(s)
                  }
                  func main() {
                      s := "abcd"
                      for i, n := 0, length(s); i < n; i++ {     // 避免多次调用 length 函数。
                          println(i, s[i])
                      } 
                  }

                  image.gif

                  输出:

                  call length.
                      0 97
                      1 98
                      2 99
                      3 100

                  image.gif

                  20200219220759892.png

                  流程控制总结image.gif

                  参考链接:

                  循环语句for · Go语言中文文档


                  目录
                  相关文章
                  |
                  4天前
                  |
                  供应链 Go
                  掌握Go语言:利用Go语言的单向通道和select语句,提升库存管理效率(21)
                  掌握Go语言:利用Go语言的单向通道和select语句,提升库存管理效率(21)
                  |
                  4天前
                  |
                  Go
                  Go-新手速成-流程语句
                  Go-新手速成-流程语句
                  |
                  4天前
                  |
                  程序员 Go
                  Golang深入浅出之-Select语句在Go并发编程中的应用
                  【4月更文挑战第23天】Go语言中的`select`语句是并发编程的关键,用于协调多个通道的读写。它会阻塞直到某个通道操作可行,执行对应的代码块。常见问题包括忘记初始化通道、死锁和忽视`default`分支。要解决这些问题,需确保通道初始化、避免死锁并添加`default`分支以处理无数据可用的情况。理解并妥善处理这些问题能帮助编写更高效、健壮的并发程序。结合使用`context.Context`和定时器等工具,可提升`select`的灵活性和可控性。
                  28 2
                  |
                  4天前
                  |
                  Go 开发者
                  Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
                  【4月更文挑战第21天】本文介绍了Go语言中的流程控制语句,包括`if`、`switch`和`for`循环。`if`语句支持简洁的语法和初始化语句,但需注意比较运算符的使用。`switch`语句提供多分支匹配,可省略`break`,同时支持不带表达式的形式。`for`循环有多种形式,如基本循环和`for-range`遍历,遍历时修改原集合可能导致未定义行为。理解并避免易错点能提高代码质量和稳定性。通过实践代码示例,可以更好地掌握Go语言的流程控制。
                  22 3
                  Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
                  |
                  4天前
                  |
                  Cloud Native 网络协议 Go
                  [云原生] Go web工作流程
                  [云原生] Go web工作流程
                  |
                  7月前
                  |
                  Go 开发者
                  Go 语言怎么优化重复的 if err != nil 样板代码?
                  Go 语言怎么优化重复的 if err != nil 样板代码?
                  57 0
                  |
                  4天前
                  |
                  Go
                  Go并发编程:玩转select语句
                  Go并发编程:玩转select语句
                  30 0
                  Go并发编程:玩转select语句
                  |
                  4天前
                  |
                  存储 编译器 Go
                  go语言第一章(变量,if, switch)
                  go语言第一章(变量,if, switch)
                  26 0
                  |
                  4天前
                  |
                  JavaScript 前端开发 Java
                  Go 语言中的 Switch 语句详解
                  使用switch语句来选择要执行的多个代码块中的一个。 在Go中的switch语句类似于C、C++、Java、JavaScript和PHP中的switch语句。不同之处在于它只执行匹配的case,因此不需要使用break语句。
                  98 1
                  |
                  5月前
                  |
                  Go
                  go 缓冲区循环 以及 select选择
                  go 缓冲区循环 以及 select选择
                  27 0