【Go语言基础【10】】循环语句:for、无限循环、for range、嵌套

发布时间:2026/11/3 9:21:52
【Go语言基础【10】】循环语句:for、无限循环、for range、嵌套

文章目录

  • 零、概述
  • 一、for循环基础
    • 1. 完整格式(三部分控制)
    • 2. 省略格式(简化写法)
  • 二、无限循环
  • 三、for range遍历
  • 四、嵌套循环
  • 五、循环控制语句
    • 1. break:退出循环
    • 2. continue:跳过本次迭代
    • 3. goto:无条件跳转(谨慎使用)

零、概述

场景推荐写法示例代码
固定次数循环完整格式for i:=0; i<n; i++for i:=0; i<10; i++ { ... }
条件循环(类似while)省略格式for condition { ... }for x<100 { x *= 2; }
遍历集合for rangefor idx, val := range slice { ... }
多层循环中断break labelouter: for { if cond { break outer; } }
跳过当前迭代continueif val%2==0 { continue; }

注意:

  1. 循环变量作用域:
    • 完整格式中,i := 0声明的变量作用域仅限循环体内。
    • 提前声明的循环变量(如var i int)作用域为外层块。
  2. for range的坑:
    • 遍历切片时,value是元素副本,修改value不影响原切片,需通过索引修改。
    • 遍历Map时,每次迭代顺序不确定(底层哈希表特性)。
  3. 性能优化:
    • 避免在循环中执行高耗时操作(如网络请求、文件IO)。
    • 大切片遍历时,可使用for i := 0; i < len(slice); i++替代for range,避免复制值。

一、for循环基础

1. 完整格式(三部分控制)

for[初始化语句];[条件表达式];[后置语句]{// 循环体}
  • 初始化语句:设置循环变量初始值(如i := 0),仅执行一次。
  • 条件表达式:决定循环是否继续(如i < 10),每次循环前判断。
  • 后置语句:更新循环变量(如i++),每次循环后执行。

示例:计算1-100之和

sum:=0fori:=1;i<=100;i++{sum+=i}fmt.Println("总和:",sum)// 输出:5050

2. 省略格式(简化写法)

(1)省略初始化语句

variint=1// 提前声明循环变量for;i<=10;i++{// 省略初始化部分fmt.Print(i," ")}

(2)省略后置语句

fori:=1;i<=10;{// 省略 i++,在循环体内更新fmt.Print(i," ")i++}

(3)完全省略(类似while循环)

sum:=1forsum<100{// 仅保留条件表达式,等价于 while(sum < 100)sum*=2// 循环体内更新变量}fmt.Println("最终值:",sum)// 输出:128

二、无限循环

省略条件表达式即可实现无限循环,需通过break、return等语句退出。

语法形式

for{// 无限循环// 循环体ifcondition{break// 满足条件时退出}}

示例:模拟重试机制

attempts:=0for{ifattempts>=3{fmt.Println("重试失败")break}fmt.Println("尝试第",attempts+1,"次")ifsuccess:=tryOperation();success{// 假设 tryOperation 返回是否成功fmt.Println("操作成功")break}attempts++}

三、for range遍历

for range是Go语言特有的遍历方式,可迭代数组、切片、Map、字符串、通道(Channel)等数据结构。

语法格式

for[index,value]:=rangeiterable{// 循环体}
  • 数组/切片:index为索引,value为元素值(副本)。
  • Map:index为键(Key),value为值(Value)。
  • 字符串:index为字节偏移量,value为 Unicode 码点(rune类型)。


示例:遍历切片和Map
(1)遍历切片

nums:=[]int{1,3,5,7}foridx,num:=rangenums{nums[idx]=num*2// 通过索引修改原切片fmt.Printf("索引 %d,值 %d\n",idx,num)}fmt.Println("修改后的切片:",nums)// 输出:[2 6 10 14]

(2)遍历Map

user:=map[string]int{"Alice":25,"Bob":30}forname,age:=rangeuser{fmt.Printf("%s 的年龄是 %d\n",name,age)}// 输出顺序不固定,可能为:// Alice 的年龄是 25// Bob 的年龄是 30

(3)遍历字符串(Unicode支持)

str:="Go语言"foridx,r:=rangestr{// r 为 rune 类型,代表 Unicode 字符fmt.Printf("字符 %c 位于字节位置 %d\n",r,idx)}// 输出:// 字符 G 位于字节位置 0// 字符 o 位于字节位置 1// 字符 语 位于字节位置 2(UTF-8编码占3字节)// 字符 言 位于字节位置 5(UTF-8编码占3字节)

四、嵌套循环

在循环体内包含另一个循环,适用于需要多层迭代的场景(如矩阵运算、生成表格等)。

示例1:打印九九乘法表

fori:=1;i<=9;i++{forj:=1;j<=i;j++{fmt.Printf("%d×%d=%-3d",j,i,i*j)// %-3d 左对齐,宽度3}fmt.Println()// 每行结束换行}


示例2:查找素数(埃拉托斯特尼筛法)

max:=100isPrime:=make([]bool,max+1)//make//用于创建并初始化引用类型(切片、map、通道)。//它会为这些类型分配内存空间,并返回一个初始化后的类型实例(非 nil)。fori:=2;i<=max;i++{isPrime[i]=true// 初始化为素数}fori:=2;i*i<=max;i++{// 只检查到平方根ifisPrime[i]{forj:=i*i;j<=max;j+=i{// 标记非素数isPrime[j]=false}}}// 输出结果fmt.Print("素数列表:")fori:=2;i<=max;i++{ifisPrime[i]{fmt.Print(i," ")}}

五、循环控制语句

1. break:退出循环

  • 作用:终止当前循环,跳出循环体。
  • 标签用法:在嵌套循环中,break [标签]可退出指定标签的外层循环。

示例:带标签的break

outer:fori:=0;i<3;i++{forj:=0;j<3;j++{ifi==1&&j==1{breakouter// 退出外层循环}fmt.Printf("(%d, %d) ",i,j)}}// 输出:(0,0) (0,1) (0,2) (1,0)

2. continue:跳过本次迭代

  • 作用:跳过当前迭代的剩余语句,直接进入下一次迭代。

示例:打印奇数

fori:=1;i<=10;i++{ifi%2==0{continue// 跳过偶数}fmt.Print(i," ")// 输出:1 3 5 7 9}

3. goto:无条件跳转(谨慎使用)

作用:跳转到指定标签(Label)处执行代码,可能破坏代码结构,需谨慎使用。

示例:错误处理中的快速跳转

file,err:=os.Open("data.txt")iferr!=nil{gotoERROR// 跳转到错误处理标签}// 处理文件逻辑file.Close()returnERROR:fmt.Println("打开文件失败:",err)