banner
Pi3

Pi3

记录学习、生活和成长
github
telegram
x
zhihu
email

Go语言入门7:循环语句

Go 语言入门基础学习笔记之 Go 语言的循环语句

golang

循环语句#

for 循环#

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

  1. 和 C 语言的 for 一样:
for init; condition; post { }
  • init: 一般为赋值表达式,给控制变量赋初值;
  • condition关系表达式或逻辑表达式,循环控制条件;
  • post: 一般为赋值表达式,给控制变量增量或减量。

init 和 post 参数是可选的,我们可以直接省略它,类似 While 语句。

  1. 和 C 的 while 一样:
for condition { }
  1. 和 C 的 for(;;) 一样:
// 无限循环
for { } 
// 或者
for true { }

范围 Range

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

for key, value := range oldMap {
    newMap[key] = value
}

以上代码中的 key 和 value 是可以省略。

如果只想读取 key,格式如下:

for key := range oldMap
// 或者
for key, _ := range oldMap

如果只想读取 value,格式如下:

for _, value := range oldMap

因为 Go 语言中所有声明的变量都必须被使用,因此可以使用 _ 来替代。

循环控制语句#

控制语句描述
break 语句经常用于中断当前 for 循环或跳出 switch 语句
continue 语句跳过当前循环的剩余语句,然后继续进行下一轮循环。
goto 语句将控制转移到被标记的语句。

break 语句#

在 Go 语言中,break 语句用于终止当前循环或者 switch 语句的执行,并跳出该循环或者 switch 语句的代码块。

break 语句可以用于以下几个方面:

  • 用于循环语句中跳出循环,并开始执行循环之后的语句。
  • break 在 switch 语句中在执行一条 case 后跳出语句的作用。
  • break 可应用在 select 语句中,用于跳出 select 语句不再执行。
  • 在多重循环中,可以用标号 label 标出想 break 的循环。

多重循环中使用标记不使用标记的区别:

package main

import "fmt"

func main() {

   // 不使用标记
   fmt.Println("---- break ----")
   for i := 1; i <= 3; i++ {
      fmt.Printf("i: %d\n", i)
      for i2 := 11; i2 <= 13; i2++ {
         fmt.Printf("i2: %d\n", i2)
         break
      }
   }

   // 使用标记
   fmt.Println("---- break label ----")
   re:
      for i := 1; i <= 3; i++ {
         fmt.Printf("i: %d\n", i)
         for i2 := 11; i2 <= 13; i2++ {
         fmt.Printf("i2: %d\n", i2)
         break re
      }
   }
}

// 输出结果
---- break ----
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11
---- break label ----
i: 1
i2: 11

由此可知,不使用标记的 break 只能跳出当前的循环。而使用标记的 break 可以指定跳出的循环。

在 Go 语言中,break 语句在 select 语句中的应用是相对特殊的。由于 select 语句的特性,有些情况 break 语句并不能直接用于跳出 select 语句本身,因为 select 语句是非阻塞的,它会一直等待所有的通信操作都准备就绪。

正如以下实例,select 被嵌套在一个无线循环语句中,因此 break 语句只会跳出 select 语句,而不会跳出外层的 for 循环。如果你想跳出外层的 for 循环,可以使用 break + 标签 (标记) 来实现。除此之外也可以使用 return 或者 goto 语句。

当然相同情况下的 switch 语句也可以使用这三种办法

package main

import (
    "fmt"
    "time"
)

func process(ch chan int) {
Loop:
    for {
        select {
        case val := <-ch:
            fmt.Println("Received value:", val)
            // 执行一些逻辑
            if val == 5 {
                break Loop
                // 或者用 return 提前结束当前函数执行
                // 也可以用 goto EndLoop 跳到函数最后一行
            }
        default:
            fmt.Println("No value received yet.")
            time.Sleep(500 * time.Millisecond)
        }
    }
EndLoop:
}

func main() {
    ch := make(chan int)

    go process(ch)

    time.Sleep(2 * time.Second)
    ch <- 1
    time.Sleep(1 * time.Second)
    ch <- 3
    time.Sleep(1 * time.Second)
    ch <- 5
    time.Sleep(1 * time.Second)
    ch <- 7

    time.Sleep(2 * time.Second)
}

// 输出结果
No value received yet.
No value received yet.
Received value: 1
No value received yet.
Received value: 3
No value received yet.
Received value: 5

continue 语句#

Go 语言的 continue 语句有点像 break 语句。但是 continue 不是跳出循环,而是跳过当前循环执行下一次循环语句。

在多重循环中,可以用标号 label 标出想 continue 的循环。

多重循环使用标记不使用标记的区别:

package main

import "fmt"

func main() {

    // 不使用标记
    fmt.Println("---- continue ---- ")
    for i := 1; i <= 3; i++ {
        fmt.Printf("i: %d\n", i)
            for i2 := 11; i2 <= 13; i2++ {
                fmt.Printf("i2: %d\n", i2)
                continue
            }
    }

    // 使用标记
    fmt.Println("---- continue label ----")
    re:
        for i := 1; i <= 3; i++ {
            fmt.Printf("i: %d\n", i)
                for i2 := 11; i2 <= 13; i2++ {
                    fmt.Printf("i2: %d\n", i2)
                    continue re
                }
        }
}

// 输出结果
---- continue ---- 
i: 1
i2: 11
i2: 12
i2: 13
i: 2
i2: 11
i2: 12
i2: 13
i: 3
i2: 11
i2: 12
i2: 13
---- continue label ----
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11

goto 语句#

Go 语言的 goto 语句可以无条件地转移到过程中指定的行。

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\n", a)
      a++     
   }  
}

// 输出结果
a的值为 : 10
a的值为 : 11
a的值为 : 12
a的值为 : 13
a的值为 : 14
a的值为 : 16
a的值为 : 17
a的值为 : 18
a的值为 : 19
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。