循环语句 #

一、for循环概述 #

Go只有一种循环关键字for,但支持多种形式。

二、标准for循环 #

2.1 基本语法 #

go
for 初始化; 条件; 后置语句 {
    // 循环体
}

2.2 示例 #

go
for i := 0; i < 5; i++ {
    fmt.Println(i)
}
// 输出: 0 1 2 3 4

2.3 省略部分 #

省略初始化:

go
i := 0
for ; i < 5; i++ {
    fmt.Println(i)
}

省略后置语句:

go
for i := 0; i < 5; {
    fmt.Println(i)
    i++
}

省略条件和后置(相当于while):

go
i := 0
for i < 5 {
    fmt.Println(i)
    i++
}

三、while风格循环 #

Go没有while关键字,使用for模拟:

go
// 相当于 while(condition)
i := 0
for i < 5 {
    fmt.Println(i)
    i++
}

// 相当于 while(true)
for {
    // 无限循环
    if someCondition {
        break
    }
}

四、死循环 #

4.1 基本形式 #

go
for {
    fmt.Println("无限循环")
}

4.2 带退出条件 #

go
for {
    result := doSomething()
    if result == "done" {
        break
    }
}

五、for-range循环 #

5.1 遍历切片/数组 #

go
numbers := []int{1, 2, 3, 4, 5}

for index, value := range numbers {
    fmt.Printf("索引: %d, 值: %d\n", index, value)
}

省略索引:

go
for _, value := range numbers {
    fmt.Println(value)
}

省略值:

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

5.2 遍历映射 #

go
scores := map[string]int{
    "Alice": 90,
    "Bob":   85,
    "Carol": 95,
}

for name, score := range scores {
    fmt.Printf("%s: %d\n", name, score)
}

5.3 遍历字符串 #

go
s := "世界"

// 按字节遍历
for i := 0; i < len(s); i++ {
    fmt.Printf("%d: %x\n", i, s[i])
}

// 按rune遍历
for i, r := range s {
    fmt.Printf("%d: %c\n", i, r)
}

5.4 遍历通道 #

go
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)

for v := range ch {
    fmt.Println(v)
}

六、嵌套循环 #

go
for i := 1; i <= 9; i++ {
    for j := 1; j <= i; j++ {
        fmt.Printf("%d*%d=%d\t", j, i, i*j)
    }
    fmt.Println()
}

七、循环控制 #

7.1 break #

跳出当前循环:

go
for i := 0; i < 10; i++ {
    if i == 5 {
        break
    }
    fmt.Println(i)
}
// 输出: 0 1 2 3 4

7.2 continue #

跳过本次迭代:

go
for i := 0; i < 5; i++ {
    if i == 2 {
        continue
    }
    fmt.Println(i)
}
// 输出: 0 1 3 4

7.3 标签 #

用于跳出嵌套循环:

go
outer:
for i := 0; i < 3; i++ {
    for j := 0; j < 3; j++ {
        if i == 1 && j == 1 {
            break outer
        }
        fmt.Printf("(%d, %d) ", i, j)
    }
}
// 输出: (0, 0) (0, 1) (0, 2) (1, 0)

continue使用标签:

go
outer:
for i := 0; i < 3; i++ {
    for j := 0; j < 3; j++ {
        if j == 1 {
            continue outer
        }
        fmt.Printf("(%d, %d) ", i, j)
    }
}
// 输出: (0, 0) (1, 0) (2, 0)

八、实际应用 #

8.1 求和 #

go
sum := 0
for i := 1; i <= 100; i++ {
    sum += i
}
fmt.Println(sum)  // 5050

8.2 查找元素 #

go
func find(numbers []int, target int) int {
    for i, n := range numbers {
        if n == target {
            return i
        }
    }
    return -1
}

8.3 过滤 #

go
func filter(numbers []int, condition func(int) bool) []int {
    var result []int
    for _, n := range numbers {
        if condition(n) {
            result = append(result, n)
        }
    }
    return result
}

evens := filter([]int{1, 2, 3, 4, 5}, func(n int) bool {
    return n%2 == 0
})
fmt.Println(evens)  // [2 4]

8.4 重试机制 #

go
func retry(fn func() error, maxAttempts int) error {
    for i := 0; i < maxAttempts; i++ {
        if err := fn(); err == nil {
            return nil
        }
        time.Sleep(time.Second)
    }
    return errors.New("max attempts reached")
}

8.5 批量处理 #

go
func batchProcess(items []string, batchSize int, process func([]string)) {
    for i := 0; i < len(items); i += batchSize {
        end := i + batchSize
        if end > len(items) {
            end = len(items)
        }
        process(items[i:end])
    }
}

九、常见错误 #

9.1 循环变量作用域 #

go
var funcs []func()
for i := 0; i < 3; i++ {
    funcs = append(funcs, func() {
        fmt.Println(i)
    })
}
for _, f := range funcs {
    f()
}
// 输出: 3 3 3(不是 0 1 2)

// 解决方法
for i := 0; i < 3; i++ {
    i := i  // 创建新变量
    funcs = append(funcs, func() {
        fmt.Println(i)
    })
}

9.2 range值是副本 #

go
type Person struct {
    Name string
    Age  int
}

people := []Person{
    {"Alice", 25},
    {"Bob", 30},
}

for _, p := range people {
    p.Age = 0  // 修改的是副本
}
fmt.Println(people)  // Age未改变

// 正确做法
for i := range people {
    people[i].Age = 0
}

9.3 无限循环 #

go
i := 0
for i < 5 {
    fmt.Println(i)
    // 忘记i++,导致无限循环
}

十、最佳实践 #

10.1 选择合适的循环形式 #

go
// 已知次数:标准for
for i := 0; i < n; i++ {}

// 遍历集合:for-range
for _, v := range slice {}

// 条件循环:省略初始化和后置
for condition {}

10.2 避免在循环中创建闭包 #

go
// 不好
for _, item := range items {
    go func() {
        process(item)  // 可能使用最后一个item
    }()
}

// 好
for _, item := range items {
    item := item
    go func() {
        process(item)
    }()
}

10.3 使用标签提高可读性 #

go
found:
for _, row := range matrix {
    for _, cell := range row {
        if cell == target {
            break found
        }
    }
}

十一、总结 #

for循环要点:

形式 说明
for init; cond; post {} 标准for循环
for cond {} while风格
for {} 死循环
for k, v := range coll {} range遍历

关键点:

  1. 唯一循环关键字:Go只有for
  2. 灵活形式:支持多种循环形式
  3. for-range:遍历数组、切片、映射、通道、字符串
  4. 标签:break/continue可以配合标签使用
  5. 变量作用域:注意循环变量在闭包中的问题

准备好学习循环控制了吗?让我们进入下一章!

最后更新:2026-03-26