GO语言基础教程(39)Go循环语句:Go循环暴击:for循环的三副面孔让你秀出天际!

兄弟们,姐妹们,代码狗们!今天咱们来聊点Go语言里那个你天天用,却可能从未真正懂它的家伙——循环语句!

别跟我说什么“循环不就是重复执行代码嘛”,要是这么想,那你可太小看Go的循环了!在Go的世界里,循环只有一位大哥叫for,但这位大哥却有三副面孔,能扮演其他语言里forwhileforeach所有的角色!

基础for循环:直男式表白

先来看看最基础的for循环,这哥们儿长得特别直白:

for 初始化语句; 条件表达式; 后续操作 {
    // 循环体
}

来个实际例子,假设你要打印0到4:

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        fmt.Printf("当前是第%d次循环\n", i)
    }
}

运行结果:

当前是第0次循环
当前是第1次循环
当前是第2次循环
当前是第3次循环
当前是第4次循环

看见没?Go的for循环不需要小括号!这是跟其他语言的一大区别。忘了去掉括号?编译器分分钟教你做人!

但这里有个小细节:变量i的作用域只在循环内部。出了这个循环,i就跟你前任一样——不存在了!

第二副面孔:while循环的替身

我知道你在想什么:“Go里有没有while循环?” 答案是:没有专门的while关键字,但for能完美cosplay!

Go里的while风格循环长这样:

for 条件表达式 {
    // 循环体
}

来个实际场景:假设你在写游戏,玩家血量大于0就继续游戏:

package main

import "fmt"

func main() {
    hp := 10
    
    for hp > 0 {
        fmt.Printf("玩家还在战斗,剩余血量:%d\n", hp)
        hp-- // 每次循环血量减1
    }
    
    fmt.Println("游戏结束!")
}

运行结果:

玩家还在战斗,剩余血量:10
玩家还在战斗,剩余血量:9
...
玩家还在战斗,剩余血量:1
游戏结束!

这种循环在你不知道具体要循环多少次,只知道循环条件时特别有用!

无限循环:代码界的鬼打墙

有时候你需要一个永远执行的循环,比如服务器的主循环:

for {
    // 这个循环会一直执行,直到遇见break或return
}

但小心!这玩意要是没设置退出条件,就真成鬼打墙了:

package main

import (
    "fmt"
    "time"
)

func main() {
    count := 0
    for {
        fmt.Printf("我已经循环了%d次...\n", count)
        count++
        time.Sleep(1 * time.Second) // 每秒一次
        
        if count >= 5 {
            fmt.Println("够了够了,停!")
            break // break是跳出循环的关键!
        }
    }
}

运行结果:

我已经循环了0次...
我已经循环了1次...
我已经循环了2次...
我已经循环了3次...
我已经循环了4次...
够了够了,停!

第三副面孔:foreach的优雅化身

在其他语言里遍历数组、切片时常用foreach,Go里用for range

for 索引, 值 := range 集合 {
    // 循环体
}

实战一下,遍历一个切片:

package main

import "fmt"

func main() {
    fruits := []string{"苹果", "香蕉", "橙子", "草莓"}
    
    for index, fruit := range fruits {
        fmt.Printf("第%d个水果是:%s\n", index, fruit)
    }
}

运行结果:

第0个水果是:苹果
第1个水果是:香蕉
第2个水果是:橙子
第3个水果是:草莓

如果你不需要索引,用下划线_忽略:

for _, fruit := range fruits {
    fmt.Printf("我喜欢吃:%s\n", fruit)
}

循环控制:break和continue的骚操作

break:立即结束整个循环,就像上课时突然火警响了,大家都得离开教室。

continue:跳过本次循环剩余代码,直接进入下一次循环,就像上课时你尿急去厕所,回来继续听课。

来看个复杂点的例子:

package main

import "fmt"

func main() {
    fmt.Println("找出0-9之间的所有奇数:")
    
    for i := 0; i < 10; i++ {
        if i%2 == 0 { // 如果是偶数
            continue // 跳过这次循环
        }
        fmt.Printf("%d是奇数!\n", i)
        
        if i == 7 {
            fmt.Println("遇到7就提前结束!")
            break
        }
    }
}

运行结果:

找出0-9之间的所有奇数!
1是奇数!
3是奇数!
5是奇数!
7是奇数!
遇到7就提前结束!

标签循环:高级玩家的传送门

这是Go循环里最骚的功能之一——带标签的break和continue!让你能从多层循环中直接跳转到指定位置。

package main

import "fmt"

func main() {
    fmt.Println("标签循环演示:")
    
// 外层循环标签
OuterLoop:
    for i := 0; i < 3; i++ {
        fmt.Printf("外层循环i=%d\n", i)
        
        for j := 0; j < 3; j++ {
            fmt.Printf("  内层循环j=%d\n", j)
            
            if i == 1 && j == 1 {
                fmt.Println("触发条件,跳出到外层循环!")
                continue OuterLoop // 直接继续外层循环的下一次
            }
        }
    }
}

运行结果:

外层循环i=0
  内层循环j=0
  内层循环j=1
  内层循环j=2
外层循环i=1
  内层循环j=0
  内层循环j=1
触发条件,跳出到外层循环!
外层循环i=2
  内层循环j=0
  内层循环j=1
  内层循环j=2

实战案例:摸鱼时刻表

来点实际的!假设你要做个工作日摸鱼提醒:

package main

import (
    "fmt"
    "time"
)

func main() {
    workTasks := []string{"写代码", "开会", "写文档", "调试bug", "代码review"}
    breakTimes := []int{2, 4} // 在第2和第4个任务后摸鱼
    
    fmt.Println("=== 工作日摸鱼时刻表 ===")
    
    taskCount := 0
    for taskCount < len(workTasks) {
        fmt.Printf("当前任务:%s\n", workTasks[taskCount])
        
        // 检查是不是摸鱼时间
        for _, breakTime := range breakTimes {
            if taskCount == breakTime {
                fmt.Println("   -> 摸鱼时间到!刷会儿微博...")
                time.Sleep(1 * time.Second) // 模拟摸鱼1秒
            }
        }
        
        taskCount++
        
        // 防止无限循环的保险
        if taskCount > 10 {
            fmt.Println("警告:任务太多,摸鱼失败!")
            break
        }
    }
    
    fmt.Println("下班啦!")
}

性能小贴士

  1. 预分配切片容量:在循环前用make([]T, 0, capacity)预分配,避免循环中反复扩容
  2. 避免在循环内创建大对象:大的内存分配放到循环外面
  3. range返回的是副本:修改元素要用索引方式
// 错误示范
for _, value := range slice {
    value = newValue // 这不会修改原切片!
}

// 正确做法
for i := range slice {
    slice[i] = newValue // 这样才会修改原切片
}

常见坑点总结

  • 忘记break导致无限循环
  • 在循环外使用循环变量
  • 修改range迭代的副本以为修改了原值
  • 并发访问共享数据没加锁

结语

Go的循环看似简单,实则内涵丰富!从基础的for循环到灵活的while替代,再到优雅的range遍历,每一招都用好了都能让你的代码更简洁高效。

记住,好的循环代码应该像好笑话一样——不需要解释就能看懂。多用有意义的变量名,保持循环简短,适当使用break和continue,你的代码质量立马提升一个level!

现在,去写点漂亮的循环代码吧!如果还有疑问,记住Go箴言:少即是多,简单就是美


本文示例代码在Go 1.19+测试通过,摸鱼建议根据实际工作情况酌情使用,被老板抓到时别说是跟我学的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值