Skip to content

Go 循环

作者: 小满zs 链接:https://go-docs.pages.dev/

五谷轮回

Go 里只有一种循环关键字:for。没有 while、也没有 do-while,所有循环形态都靠 for 表达。

普通 for 循环

我们声明了一个切片,用经典的「初始化;条件;步进」写法遍历:

go
package main

import "fmt"

func main() {
  var hobbys = []string{"吃饭", "睡觉", "打豆豆"} 
  for i := 0; i < len(hobbys); i++ {
    fmt.Println(hobbys[i])
  }
}

for 后面分成三段,用分号隔开:

部分作用上面示例
初始化循环开始前执行一次i := 0
条件每次循环前判断,为真才继续i < len(hobbys)
步进每次循环体结束后执行i++

输出依次为:吃饭睡觉打豆豆

三段都可以省略。只留条件时,就相当于其他语言里的 while

go
package main

import "fmt"

func main() {
  i := 0
  for i < 3 {
    fmt.Println(i)
    i++
  }
}

条件也省略时,就是无限循环,需要靠 break 自己跳出:

go
package main

import "fmt"

func main() {
  i := 0
  for {
    fmt.Println(i)
    i++
    if i >= 3 {
      break
    }
  }
}

range 循环

遍历切片、数组、字符串、map、channel 时,更常用 range,写法更简洁:

go
package main

import "fmt"

func main() {
  var hobbys = []string{"吃饭", "睡觉", "打豆豆"} 
  for index, hobby := range hobbys {
    fmt.Println(index, hobby)
  }
}

range 每次迭代会返回两个值:

  • 第一个是下标(或 mapkey
  • 第二个是对应的元素值

输出为:

bash
0 吃饭
1 睡觉
2 打豆豆

如果只要值、不要下标,用 _ 丢掉第一个返回值:

go
for index := range hobbys {
  fmt.Println(index)
}

遍历 map

go
package main

import "fmt"

func main() {
  person := map[string]string{ 
    "name": "张三",
    "city": "杭州",
  }
  for key, value := range person {
    fmt.Println(key, value)
  }
}

注意:map 的遍历顺序不固定,每次运行打印顺序可能不同。

遍历字符串

go
package main

import "fmt"

func main() {
  text := "你好Go"
  for index, char := range text {
    fmt.Printf("下标 %d,字符 %c\n", index, char)
  }
}

range 遍历字符串时,拿到的是 Unicode 码点(rune),不是单个字节。

像「你」「好」这种汉字各占 3 个字节,下标会按字节位置跳着走。

text
下标 0,字符 你
下标 3,字符 好
下标 6,字符 G
下标 7,字符 o
写法适用场景
for i := 0; i < len(x); i++需要精确控制下标、步长,或从中间开始 / 倒序遍历
for i, v := range x顺序遍历切片、数组、字符串、map

break 与 continue

循环中经常要「提前结束」或「跳过本次」:

关键字含义
break立刻跳出当前循环
continue跳过本次剩余代码,进入下一次循环

break:跳出循环

go
package main

import "fmt"

func main() {
  hobbys := []string{"吃饭", "睡觉", "打豆豆"} 
  for _, hobby := range hobbys {
    if hobby == "睡觉" {
      break
    }
    fmt.Println(hobby)
  }
}

遇到「睡觉」就 break,后面的元素不再遍历。输出只有:吃饭

continue:跳过本次

go
package main

import "fmt"

func main() {
  hobbys := []string{"吃饭", "睡觉", "打豆豆"} 
  for _, hobby := range hobbys {
    if hobby == "睡觉" {
      continue
    }
    fmt.Println(hobby)
  }
}

遇到「睡觉」就 continue,跳过打印,但循环继续。输出为:吃饭打豆豆

带标签的 break

多层循环嵌套时,普通 break 只跳出最内层。若要一次跳出外层,可以给循环加标签:

go
package main

import "fmt"

func main() {
Outer: 
  for i := 0; i < 3; i++ {
    for j := 0; j < 3; j++ {
      if i == 1 && j == 1 {
        break Outer 
      }
      fmt.Println(i, j)
    }
  }
}

break Outer 会直接跳出名为 Outer 的那一层循环。continue 也可以配合标签使用,表示跳到指定循环的下一次迭代。

goto

goto 可以跳转到同一函数内的某个标签位置。能用,但可读性往往更差,日常代码里更推荐 break / continue / return

go
package main

import "fmt"

func main() {
  i := 0
Loop:
  fmt.Println(i)
  i++
  if i < 3 {
    goto Loop 
  }
}

上面用 goto 模拟了一个简单循环:打印 012。实际项目中除非处理错误清理这类特殊场景,否则尽量少用。

作业

  1. 普通 for:声明一个 110 的循环,打印所有偶数。
    答案
    go
    fmt.Println("1. 普通 for:打印 1 到 10 中的所有偶数")
    for i := 1; i <= 10; i++ {
    	if i%2 == 0 {
    		fmt.Println(i)
    	}
    }
  2. range 练习:定义切片 []string{"春", "夏", "秋", "冬"},分别用「只要下标」「只要值」「下标+值」三种 range 写法打印。
    答案
    go
    fmt.Println("2. range 练习")
    seasons := []string{"春", "夏", "秋", "冬"}
    fmt.Println("只要下标:")
    for i := range seasons {
    	fmt.Println(i)
    }
    fmt.Println("只要值:")
    for _, v := range seasons {
    	fmt.Println(v)
    }
    fmt.Println("下标+值:")
    for i, v := range seasons {
    	fmt.Println(i, v)
    }
  3. break / continue:遍历 120,遇到能被 3 整除的数就 continue 跳过;一旦遇到大于 15 的数就 break 结束。观察最终打印了哪些数。
    答案
    go
    fmt.Println("3. break / continue")
    for i := 1; i <= 20; i++ {
    	if i%3 == 0 {
    		continue
    	}
    	if i > 15 {
    		break
    	}
    	fmt.Println(i)
    }
  4. 类 while:用「只写条件」的 for(不要初始化段和步进段)计算 1 + 2 + ... + 100 的和并打印。
    答案
    go
    fmt.Println("4. 类 while:计算 1 + 2 + ... + 100 的和")
    sum, i := 0, 1
    for i <= 100 {
    	sum += i
    	i++
    }
    fmt.Println("和:", sum)
  5. 综合练习:定义 map[string]int 表示各科分数(如语文、数学、英语),用 range 遍历:低于 60 的科目打印「不及格」,其余打印「及格」,并统计及格科目数量。
    答案
    go
    fmt.Println("5. 综合练习")
    scores := map[string]int{
    	"语文": 85,
    	"数学": 92,
    	"英语": 58,
    	"物理": 73,
    	"化学": 45,
    }
    passCount := 0
    for subject, score := range scores {
    	if score < 60 {
    		fmt.Printf("%s: %d 分 —— 不及格\n", subject, score)
    	} else {
    		fmt.Printf("%s: %d 分 —— 及格\n", subject, score)
    		passCount++
    	}
    }
    fmt.Printf("及格科目数量: %d\n", passCount)

📌 评论规则

需要 GitHub 账号登录 禁止发布广告、无关内容 请保持友善讨论