目录
  • 1、if else(分支结构)
    • 1.1 if条件判断基本写法
    • 1.2 if条件判断特殊写法
  • 2、for(循环结构)
    • 2.1 无限循环
  • 3、for range(键值循环)
    • 4、switch case
      • 5、goto(跳转到指定标签)
        • 6、break(跳出循环)
          • 7、continue(继续下次循环)

            前言:

            流程控制是每种编程语言控制逻辑走向和执行次序的重要部分,流程控制可以说是一门语言的“经脉”。

            go语言中最常用的流程控制有iffor,而switchgoto主要是为了简化代码、降低重复代码而生的结构,属于扩展类的流程控制。

            1、if else(分支结构)

            1.1 if条件判断基本写法

            go语言中if条件判断的格式如下:

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

            当表达式1的结果为true时,执行分支1,否则判断表达式2,如果满足则执行分支2,都不满足时,则执行分支3。 if判断中的else ifelse都是可选的,可以根据实际需要进行选择。

            关于 if 条件语句的使用有一些规则:

            • if 后面的条件表达式不需要使用 (),这和有些编程语言不一样,也更体现 go 语言的简洁;
            • 每个条件分支(if 或者 else)中的大括号是必须的,哪怕大括号里只有一行代码(如示例);
            • if 紧跟的大括号 { 不能独占一行,else 前的大括号 } 也不能独占一行,否则会编译不通过;
            • if……else 条件语句中还可以增加多个 else if,增加更多的条件分支。

            1.2 if条件判断特殊写法

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

            func main() {
                if i:=6; i >10 {
                    fmt.println("i>10")
                } else if  i>5 && i<=10 {
                    fmt.println("5<i<=10")
                } else {
                    fmt.println("i<=5")
                }
            }
            
            

            2、for(循环结构)

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

            for循环的基本格式如下:

            for 初始语句;条件表达式;更新语句{
                循环体语句
            }
            
            

            条件表达式返回true时循环体不停地进行循环,直到条件表达式返回false时自动退出循环。

            func fordemo() {
             for i := 0; i < 10; i++ {
              fmt.println(i)
             }
            }
            
            

            for循环的初始语句可以被忽略,但是初始语句后的分号必须要写,例如:

            func fordemo2() {
             i := 0
             for ; i < 10; i++ {
              fmt.println(i)
             }
            }
            
            

            for循环的初始语句和结束语句都可以省略,例如:

            func fordemo3() {
             i := 0
             for i < 10 {
              fmt.println(i)
              i++
             }
            }
            
            

            这种写法类似于其他编程语言中的while,在while后添加一个条件表达式,满足条件表达式时持续循环,否则结束循环。

            2.1 无限循环

            for {
                循环体语句
            }
            
            

            for循环可以通过breakgotoreturnpanic语句强制退出循环。

            go 语言中,同样支持使用 continuebreak 控制 for 循环:

            continue 可以跳出本次循环,继续执行下一个循环。

            break 可以跳出整个 for 循环,哪怕 for 循环没有执行完,也会强制终止。

            3、for range(键值循环)

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

            通过for range遍历的返回值有以下规律:

            • 数组、切片、字符串返回索引和值。
            • map返回键和值。
            • 通道(channel)只返回通道内的值。

            注意:

            与 for 不同的是,range 对每个迭代值都创建了一个拷贝。因此如果每次迭代的值内存占用很小的情况下,for 和 range 的性能几乎没有差异,但是如果每个迭代值内存占用很大,这种情况下差距就非常明显了。

            简单的例子证明 range 迭代时,返回的是拷贝。

            persons := []struct{ no int }{{no: 1}, {no: 2}, {no: 3}}
            for _, s := range persons {
                s.no += 10
            }
            for i := 0; i < len(persons); i++ {
                persons[i].no += 100
            }
            fmt.println(persons) // [{101} {102} {103}]
            
            
            • persons 是一个长度为 3 的切片,每个元素是一个结构体。
            • 使用 range 迭代时,试图将每个结构体的 no 字段增加 10,但修改无效,因为 range 返回的是拷贝。
            • 使用 for 迭代时,将每个结构体的 no 字段增加 100,修改有效

            range 在迭代过程中返回的是迭代值的拷贝,如果每次迭代的元素的内存占用很低,那么 for 和 range 的性能几乎是一样,例如 []int。但是如果迭代的元素内存占用较高,例如一个包含很多属性的 struct 结构体,那么 for 的性能将显著地高于range,有时候甚至会有上千倍的性能差异。对于这种场景,建议使用 for,如果使用 range,建议只迭代下标,通过下标访问迭代值,这种使用方式和 for 就没有区别了。如果想使用 range 同时迭代下标和值,则需要将切片/数组的元素改为指针,才能不影响性能。

            4、switch case

            使用switch语句可方便地对大量的值进行条件判断。

            func switchdemo1() {
             finger := 3
             switch finger {
             case 1:
              fmt.println("大拇指")
             case 2:
              fmt.println("食指")
             case 3:
              fmt.println("中指")
             case 4:
              fmt.println("无名指")
             case 5:
              fmt.println("小拇指")
             default:
              fmt.println("无效的输入!")
             }
            }
            
            

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

            一个分支可以有多个值,多个case值中间使用英文逗号分隔。

            func testswitch3() {
             switch n := 7; n {
             case 1, 3, 5, 7, 9:
              fmt.println("奇数")
             case 2, 4, 6, 8:
              fmt.println("偶数")
             default:
              fmt.println(n)
             }
            }
            
            

            分支还可以使用表达式,这时候switch语句后面不需要再跟判断变量:

            func switchdemo4() {
             age := 30
             switch {
             case age < 25:
              fmt.println("好好学习吧")
             case age > 25 && age < 35:
              fmt.println("好好工作吧")
             case age > 60:
              fmt.println("好好享受吧")
             default:
              fmt.println("活着真好")
             }
            }
            
            

            在 go 语言中,switch case 从上到下逐一进行判断,一旦满足条件,立即执行对应的分支并返回,其余分支不再做判断。也就是说 go 语言的 switch 在默认情况下,case 最后自带 break。这和其他编程语言不一样,比如 c 语言在 case 分支里必须要有明确的 break 才能退出一个 case。go 语言的这种设计就是为了防止忘记写 break 时,下一个 case 被执行。

            fallthrough语法可以执行满足条件的case的下一个case,是为了兼容c语言中的case设计的。

            func switchdemo5() {
             s := "a"
             switch {
             case s == "a":
              fmt.println("a")
              fallthrough
             case s == "b":
              fmt.println("b")
             case s == "c":
              fmt.println("c")
             default:
              fmt.println("...")
             }
            }
            
            

            输出:

            a
            b

            5、goto(跳转到指定标签)

            goto语句通过标签进行代码间的无条件跳转。goto语句可以在快速跳出循环、避免重复退出上有一定的帮助。go语言中使用goto语句能简化一些代码的实现过程。

             例如双层嵌套的for循环要退出时:

            func gotodemo1() {
             var breakflag bool
             for i := 0; i < 10; i++ {
              for j := 0; j < 10; j++ {
               if j == 2 {
                // 设置退出标签
                breakflag = true
                break
               }
               fmt.printf("%v-%v\n", i, j)
              }
              // 外层for循环判断
              if breakflag {
               break
              }
             }
            }
            
            

            使用goto语句能简化代码:

            func gotodemo2() {
             for i := 0; i < 10; i++ {
              for j := 0; j < 10; j++ {
               if j == 2 {
                // 设置退出标签
                goto breaktag
               }
               fmt.printf("%v-%v\n", i, j)
              }
             }
             return
             // 标签
            breaktag:
             fmt.println("结束for循环")
            }
            
            

            6、break(跳出循环)

            break语句可以结束forswitchselect的代码块。

            break语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的forswitchselect的代码块上。 举个例子:

            func breakdemo1() {
            breakdemo1:
             for i := 0; i < 10; i++ {
              for j := 0; j < 10; j++ {
               if j == 2 {
                break breakdemo1
               }
               fmt.printf("%v-%v\n", i, j)
              }
             }
             fmt.println("...")
            }
            
            

            7、continue(继续下次循环)

            continue语句可以结束当前循环,开始下一次的循环迭代过程,仅限在for循环内使用。

            continue语句后添加标签时,表示开始标签对应的循环。例如:

            func continuedemo() {
            forloop1:
             for i := 0; i < 5; i++ {
              // forloop2:
              for j := 0; j < 5; j++ {
               if i == 2 && j == 2 {
                continue forloop1
               }
               fmt.printf("%v-%v\n", i, j)
              }
             }
            }
            
            

            到此这篇关于golang通脉之流程控制详情的文章就介绍到这了,更多相关golang通脉之流程控制内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!