Go 闭包【1】基础

关于GO闭包的东西,我有点忘了,是不是有参数就马上串行执行?没参数就是并行异步执行?

并不是这样的。参数的存在与否并不决定它是同步还是异步执行。

在 Go 语言中,执行方式(串行还是异步)仅取决于你如何调用它:

  1. 串行执行(同步):直接调用函数或匿名函数。
  2. 异步执行(并行/并发):使用 go 关键字启动协程(Goroutine)。

你产生这种"模糊印象"的原因,很可能是因为在循环中使用 Goroutine 时,为了避免闭包捕获外部变量导致的作用域陷阱,通常会有两种写法:

1. 传参数的写法(推荐)

如果你通过参数传递变量,每个协程都会拿到该变量在当前时刻的副本。

复制代码
for i := 0; i < 5; i++ {
    go func(n int) {
        fmt.Println(n) // 这里会正确输出 0, 1, 2, 3, 4 (顺序随机)
    }(i) // 立即将当前的 i 作为参数传入
}

2. 不传参数的写法(容易出错)

如果不传参数,闭包会直接引用外部变量 i。因为协程启动需要时间,等协程真正开始运行的时候,循环可能已经跑完了,此时 i 的值可能已经是 5。

复制代码
for i := 0; i < 5; i++ {
    go func() {
        fmt.Println(i) // 可能全部输出 5
    }()
}

总结

  • 传参:是为了"固定"变量值,防止多个协程引用同一个一直在变的变量。
  • 不传参:闭包会引用外部作用域变量的地址。
  • 是否异步:只看有没有那个 go 关键字。
相关推荐
孔令飞30 分钟前
企业智能化升级:智能体平台设计和实现
云原生·go·ai编程
vipxieliang3 小时前
Go GC 性能优化实践:从 GOGC、GOMEMLIMIT 到分配优化
后端·go
小满zs1 天前
Go语言第十八章(架构设计)
后端·go
FungLeo2 天前
成为全栈·Go 后端篇·三轮代码审阅之后:把可读性和证据做成工程规则
golang·go·ast·静态检查·成为全栈·代码审阅
我不会起名字3222 天前
Redis 从 0 到 1(二十八):Redis 抖一下,重试把它打挂了——超时/重试/熔断的 Go 封装
redis·go·超时·熔断·重试
xyzzklk2 天前
变相解决华为Mate 8锁屏后无法建立入站网络连接
linux·运维·服务器·网络·华为·go·安卓
vipxieliang3 天前
语言对比卡:PHP vs Go vs Java 的优缺点、适用场景与「为什么选 PHP」
java·go·php
我不会起名字3224 天前
Redis 从 0 到 1(二十七):JSON 体积是 Protobuf 的 3.7 倍?3 种序列化的 Go 基准测试
redis·go·序列化·protobuf·messagepack
我不会起名字3224 天前
Redis 从 0 到 1(二十三):一个热 key 打到 10 万 QPS——hotkey 与本地缓存的 Go 实现
redis·缓存·go·qps·hotkey
Patrick_Wilson5 天前
Go 为什么需要 defer?从函数怎么收尾说起
后端·go·编程语言