Go语言里的for循环是唯一的循环关键字,但可以通过不同的声明形式覆盖大多数迭代场景。理解它的语法结构和容易出错的写法,对写出可维护的Go程序非常重要。

Go语言for循环的声明语法
Go的for循环主要有三种常见形式,本质都基于同一个关键字,只是初始化、条件和后置语句可以按需省略。
1. 标准三段式
这是最接近C语言的形式,适合已知次数的迭代。
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Println(i)
}
}
2. 条件式循环
省略初始化和后置语句,仅保留条件判断,类似其他语言的while。
package main
import "fmt"
func main() {
n := 1
for n < 100 {
n *= 2
fmt.Println(n)
}
}
3. 无限循环
完全省略条件,常用于服务监听等场景,通过break退出。
package main
import "fmt"
func main() {
for {
fmt.Println("running")
break
}
}
常见构建错误与解析
错误一:循环变量在闭包中被错误捕获
在Go 1.22之前,for循环的循环变量是复用的,如果在goroutine或defer中直接引用,可能拿到最后一次的值。
package main
import (
"fmt"
"time"
)
func main() {
for i := 0; i < 3; i++ {
// 错误写法:所有goroutine可能都打印3
go func() {
fmt.Println(i)
}()
}
time.Sleep(time.Second)
}
修正方式是在循环内创建局部副本:
package main
import (
"fmt"
"time"
)
func main() {
for i := 0; i < 3; i++ {
i := i // 创建局部变量副本
go func() {
fmt.Println(i)
}()
}
time.Sleep(time.Second)
}
错误二:在循环条件中重复短声明
有些开发者会写出类似下面的代码,导致编译报错:
package main
import "fmt"
func main() {
// 错误:每次循环都重新声明i,且作用域混乱
for i := 0; i < 5; i++ {
// 这里如果再写 i := 10 会遮蔽外层i
fmt.Println(i)
}
}
正确做法是避免在内层用:=遮蔽循环变量,需要修改就直接赋值。
错误三:误用range与for混写
遍历切片或映射应使用range,而不是手写索引越界判断。下面是错误的构建示例:
package main
import "fmt"
func main() {
s := []int{1, 2, 3}
// 错误:条件写错容易越界
for i := 0; i <= len(s); i++ {
fmt.Println(s[i])
}
}
应改为range形式:
package main
import "fmt"
func main() {
s := []int{1, 2, 3}
for _, v := range s {
fmt.Println(v)
}
}
小结
Go语言for循环语法简洁但细节不少。掌握三种声明形式,注意循环变量的作用域与闭包捕获问题,避免索引越界和错误声明,就能减少大部分构建错误。