当前位置: 首页 > news >正文

Go 中闭包的常见使用场景

在 Go 中,闭包(Closure) 是一个函数值,它引用了其定义时所在作用域中的变量。也就是说,闭包可以访问并修改外部作用域中的变量。

Go 中闭包的常见使用场景

✅ 1. 封装状态(无须结构体)

闭包可以用于封装状态,而无需显式定义结构体。

示例:计数器
func newCounter() func() int {var count intreturn func() int {count++return count}
}counter := newCounter()
fmt.Println(counter()) // 输出 1
fmt.Println(counter()) // 输出 2

闭包捕获了 count 变量,实现了私有状态。


✅ 2. 作为回调函数或事件处理

闭包常用于注册回调函数,特别是在 HTTP 处理、定时器、goroutine 中。

示例:HTTP HandlerFunc
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello from closure!")
})

闭包可以直接访问外部变量,比如数据库连接池、配置等。


✅ 3. 延迟执行 / defer 结合使用

闭包可以在 defer 中保存上下文状态。

示例:
for i := 0; i < 3; i++ {val := igo func() {fmt.Println(val)}()
}

如果不使用闭包传参或捕获局部变量,所有 goroutine 都会打印最后一个 i 的值。通过闭包捕获 val,确保每个 goroutine 拿到的是当前循环的值。


✅ 4. 装饰器模式 / 函数包装

闭包可用于增强函数行为,比如日志、限流、超时控制等。

示例:日志中间件
func withLog(fn func()) func() {return func() {fmt.Println("Before function call")fn()fmt.Println("After function call")}
}f := withLog(func() {fmt.Println("Executing main logic")
})f()

输出:

Before function call
Executing main logic
After function call

✅ 5. 惰性初始化

闭包可以用于实现单例或懒加载逻辑。

示例:
var connectOnce sync.Once
var db *sql.DBfunc GetDB() *sql.DB {connectOnce.Do(func() {var err errordb, err = sql.Open("mysql", "user:pass@/dbname")if err != nil {panic(err)}})return db
}

闭包中初始化数据库连接,只执行一次。


总结:闭包的典型用途

场景描述
状态封装实现类似类的私有状态
回调函数HTTP Handler、事件监听
延迟执行defer + 捕获变量
函数装饰添加日志、限流、权限等
单例与初始化惰性加载资源

在你的例子中,Split使用闭包来捕获 rd 变量,实现了一个线程安全的轮询分发策略,是 Go 中闭包非常典型且实用的一种写法。

http://www.xdnf.cn/news/458533.html

相关文章:

  • 【Spring Cloud Gateway】Nacos整合遇坑记:503 Service Unavailable
  • 【人工智能-agent】--Dify+Mysql+Echarts搭建了一个能“听懂”人话的数据可视化助手!
  • 全国青少年信息素养大赛 Python编程挑战赛初赛 内部集训模拟试卷八及详细答案解析
  • 数据科学和机器学习的“看家兵器”——pandas模块 之四
  • 红黑树:数据世界的平衡守护者
  • Android开发-在应用之间共享数据
  • HTML 表格与div深度解析区别及常见误区
  • 【Linux】socket网络编程基础
  • 解决ubuntu20中tracker占用过多cpu,引起的风扇狂转
  • 从算力困境到创新突破:GPUGEEK如何重塑我的AI开发之旅
  • 【HCIA】策略路由
  • C#+WPF+prism+materialdesign创建工具主界面框架
  • 安装win11硬盘分区MBR还是GPT_装win11系统分区及安装教程
  • MongoDB数据库深度解析:架构、特性与应用场景
  • MySQL-数据库分布式XA事务
  • 深度解析 Meta 开源 MR 项目《North Star》:从交互到渲染的沉浸式体验设计
  • 可解释性AI 综述《Explainable AI for Industrial Fault Diagnosis: A Systematic Review》
  • elementUI 循环出来的表单,怎么做表单校验?
  • elementUI如何动态增减表单项
  • 【Trae插件】从0到1,搭建一个能够伪装成网页内容的小说阅读Chrome插件
  • 交叉编译源码的方式移植ffmpeg-rockchip
  • 【学习心得】WSL2安装Ubuntu22.04
  • 前端npm的核心作用与使用详解
  • 【kafka】基本命令
  • Node.js 循环依赖问题详解:原理、案例与解决方案
  • 【hadoop】Kafka 安装部署
  • “傅里叶变换算法”来检测纸箱变形的简单示例
  • Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(七)
  • MySQL 8.0 OCP 1Z0-908 101-110题
  • 【Conda】环境应用至JupyterLab