zoukankan      html  css  js  c++  java
  • Go学习(3):分支循环

    程序的流程控制结构一共有三种:顺序结构,选择结构,循环结构。

    一、条件语句

    1.1 If语句

    语法格式:

    if 布尔表达式 {
       /* 在布尔表达式为 true 时执行 */
    }
    
    if 布尔表达式 {
       /* 在布尔表达式为 true 时执行 */
    } else {
      /* 在布尔表达式为 false 时执行 */
    }
    
    if 布尔表达式1 {
       /* 在布尔表达式1为 true 时执行 */
    } else if 布尔表达式2{
       /* 在布尔表达式1为 false ,布尔表达式2为true时执行 */
    } else{
       /* 在上面两个布尔表达式都为false时,执行*/
    }
    

    示例代码:

    package main
    
    import "fmt"
    
    func main() {
       /* 定义局部变量 */
       var a int = 10
     
       /* 使用 if 语句判断布尔表达式 */
       if a < 20 {
           /* 如果条件为 true 则执行以下语句 */
           fmt.Printf("a 小于 20
    " )
       }
       fmt.Printf("a 的值为 : %d
    ", a)
    }
    

    如果其中包含一个可选的语句组件(在评估条件之前执行),则还有一个变体。它的语法是

    if statement; condition {  
    }
    

    示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    func main() {  
        if num := 10; num % 2 == 0 { //checks if number is even
            fmt.Println(num,"is even") 
        }  else {
            fmt.Println(num,"is odd")
        }
    }
    

    需要注意的是,num的定义在if里,那么只能够在该if…else语句块中使用,否则编译器会报错的。

    1.2 switch 语句

    switch是一个条件语句,它计算表达式并将其与可能匹配的列表进行比较,并根据匹配执行代码块。它可以被认为是一种惯用的方式来写多个if else子句。

    switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上直下逐一测试,直到匹配为止。
    switch 语句执行的过程从上至下,直到找到匹配项,匹配项后面也不需要再加break。

    而如果switch没有表达式,它会匹配true

    Go里面switch默认相当于每个case最后带有break,匹配成功后不会自动向下执行其他case,而是跳出整个switch, 但是可以使用fallthrough强制执行后面的case代码。

    变量 var1 可以是任何类型,而 val1 和 val2 则可以是同类型的任意值。类型不被局限于常量或整数,但必须是相同的类型;或者最终结果为相同类型的表达式。
    您可以同时测试多个可能符合条件的值,使用逗号分割它们,例如:case val1, val2, val3。

    switch var1 {
        case val1:
            ...
        case val2:
            ...
        default:
            ...
    }
    

    示例代码:

    package main
    
    import "fmt"
    
    func main() {
       /* 定义局部变量 */
       var grade string = "B"
       var marks int = 90
    
       switch marks {
          case 90: grade = "A"
          case 80: grade = "B"
          case 50,60,70 : grade = "C"  //case 后可以由多个数值
          default: grade = "D"  
       }
    
       switch {
          case grade == "A" :
             fmt.Printf("优秀!
    " )     
          case grade == "B", grade == "C" :
             fmt.Printf("良好
    " )      
          case grade == "D" :
             fmt.Printf("及格
    " )      
          case grade == "F":
             fmt.Printf("不及格
    " )
          default:
             fmt.Printf("差
    " );
       }
       fmt.Printf("你的等级是 %s
    ", grade );      
    }
    

    如需贯通后续的case,就添加fallthrough

    package main
    
    import (
    	"fmt"
    )
    
    type data [2]int
    
    func main() {
    	switch x := 5; x {
    	default:
    		fmt.Println(x)
    	case 5:
    		x += 10
    		fmt.Println(x)
    		fallthrough
    	case 6:
    		x += 20
    		fmt.Println(x)
    
    	}
    
    }
    
    

    结果

    15
    35
    

    case中的表达式是可选的,可以省略。如果该表达式被省略,则被认为是switch true,并且每个case表达式都被计算为true,并执行相应的代码块。

    示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    func main() {  
        num := 75
        switch { // expression is omitted
        case num >= 0 && num <= 50:
            fmt.Println("num is greater than 0 and less than 50")
        case num >= 51 && num <= 100:
            fmt.Println("num is greater than 51 and less than 100")
        case num >= 101:
            fmt.Println("num is greater than 100")
        }
    
    }
    

    switch的注意事项

    1. case后的常量值不能重复
    2. case后可以有多个常量值
    3. fallthrough应该是某个case的最后一行。如果它出现在中间的某个地方,编译器就会抛出错误。

    Type Switch

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

    switch x.(type){
        case type:
           statement(s);      
        case type:
           statement(s); 
        /* 你可以定义任意个数的case */
        default: /* 可选 */
           statement(s);
    }
    
    package main
    
    import "fmt"
    
    func main() {
       var x interface{}
         
       switch i := x.(type) {
          case nil:	  
             fmt.Printf(" x 的类型 :%T",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("未知型")     
       }   
    }
    

    结果

    x 的类型 :<nil>
    

    1.3 select 语句

    select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。

    package main
    
    import "fmt"
    
    func main() {
       var c1, c2, c3 chan int
       var i1, i2 int
       select {
          case i1 = <-c1:
             fmt.Printf("received ", i1, " from c1
    ")
          case c2 <- i2:
             fmt.Printf("sent ", i2, " to c2
    ")
          case i3, ok := (<-c3):  // same as: i3, ok := <-c3
             if ok {
                fmt.Printf("received ", i3, " from c3
    ")
             } else {
                fmt.Printf("c3 is closed
    ")
             }
          default:
             fmt.Printf("no communication
    ")
       }    
    }
    

    运行结果:

    no communication
    
    • 每个case都必须是一个通信

    • 所有channel表达式都会被求值

    • 所有被发送的表达式都会被求值

    • 如果任意某个通信可以进行,它就执行;其他被忽略。

    • 如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。

    • 否则:

      如果有default子句,则执行该语句。

      如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。

    二、循环语句

    循环语句表示条件满足,可以反复的执行某段代码。

    for是唯一的循环语句。(Go没有while循环)

    2.1 For语句

    语法结构:

    for init; condition; post { }
    

    初始化语句只执行一次。在初始化循环之后,将检查该条件。如果条件计算为true,那么{}中的循环体将被执行,然后是post语句。post语句将在循环的每次成功迭代之后执行。在执行post语句之后,该条件将被重新检查。如果它是正确的,循环将继续执行,否则循环终止。

    示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    func main() {  
        for i := 1; i <= 10; i++ {
            fmt.Printf(" %d",i)
        }
    }
    

    在for循环中声明的变量仅在循环范围内可用。因此,i不能在外部访问循环。

    所有的三个组成部分,即初始化、条件和post都是可选的。

    for condition { }
    

    效果与while相似

    for { }
    

    效果与for(;;) 一样

    for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环

    for key, value := range oldMap {
        newMap[key] = value
    }
    
    package main
    
    import "fmt"
    
    func main() {
    
       var b int = 15
       var a int
    
       numbers := [6]int{1, 2, 3, 5} 
    
       /* for 循环 */
       for a := 0; a < 10; a++ {
          fmt.Printf("a 的值为: %d
    ", a)
       }
    
       for a < b {
          a++
          fmt.Printf("a 的值为: %d
    ", a)
          }
    
       for i,x:= range numbers {
          fmt.Printf("第 %d 位 x 的值 = %d
    ", i,x)
       }   
    }
    

    运行结果:

    a 的值为: 0
    a 的值为: 1
    a 的值为: 2
    a 的值为: 3
    a 的值为: 4
    a 的值为: 5
    a 的值为: 6
    a 的值为: 7
    a 的值为: 8
    a 的值为: 9
    a 的值为: 1
    a 的值为: 2
    a 的值为: 3
    a 的值为: 4
    a 的值为: 5
    a 的值为: 6
    a 的值为: 7
    a 的值为: 8
    a 的值为: 9
    a 的值为: 10
    a 的值为: 11
    a 的值为: 12
    a 的值为: 13
    a 的值为: 14
    a 的值为: 150 位 x 的值 = 11 位 x 的值 = 22 位 x 的值 = 33 位 x 的值 = 54 位 x 的值 = 05 位 x 的值 = 0
    

    2.2 跳出循环的语句

    2.2.1 break语句

    break:跳出循环体。break语句用于在结束其正常执行之前突然终止for循环

    示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    func main() {  
        for i := 1; i <= 10; i++ {
            if i > 5 {
                break //loop is terminated if i > 5
            }
            fmt.Printf("%d ", i)
        }
        fmt.Printf("
    line after for loop")
    }
    

    2.2.2 continue语句

    continue:跳出一次循环。continue语句用于跳过for循环的当前迭代。在continue语句后面的for循环中的所有代码将不会在当前迭代中执行。循环将继续到下一个迭代。

    示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    func main() {  
        for i := 1; i <= 10; i++ {
            if i%2 == 0 {
                continue
            }
            fmt.Printf("%d ", i)
        }
    }
    

    2.2.3 goto语句

    goto:可以无条件地转移到过程中指定的行

    package main
    
    import "fmt"
    
    func main() {
       /* 定义局部变量 */
       var a int = 10
    
       /* 循环 */
       LOOP: for a < 20 {
          if a == 15 {
             /* 跳过迭代 */
             a = a + 1
             goto LOOP
          }
          fmt.Printf("a的值为 : %d
    ", a)
          a++     
       }  
    }
    
  • 相关阅读:
    vs 2012,vs 2013问题系列
    nodejs入门
    在win7下,部署asp.net MVC 4项目到iis
    cookie和session机制区别与联系
    在Asp.net项目中禁止浏览器缓存页面
    2021年01月17日微博热搜汇总
    2021年01月16日微博热搜汇总
    2021年01月15日微博热搜汇总
    2021年01月14日微博热搜汇总
    2021年01月13日微博热搜汇总
  • 原文地址:https://www.cnblogs.com/DiZhang/p/12544854.html
Copyright © 2011-2022 走看看