如何运用Golang闭包实现轻量级对象创建的工厂模式解析?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1159个文字,预计阅读时间需要5分钟。
Go 语言中没有 class,但可以使用封装状态和行为来实现类似的功能。使用 struct 可以更轻量地实现方法。关键不在于模拟类,而是将具有相同功能的函数(如 func() int)打包成一个可复用的实例生成器。
常见错误是以为闭包必须返回 struct:其实它直接返回函数就行,比如计数器、配置化 HTTP 客户端、带默认超时的重试逻辑。
- 闭包捕获的是变量的引用,不是值——如果在循环里创建多个闭包,又共用同一个循环变量(如
i),最后所有闭包都看到同一个终值 - 想固定每次的值?用立即传参方式:
func(i int) func() { return func() { fmt.Println(i) } }(i) - 返回的函数类型要显式声明,别依赖类型推导,否则接口赋值或测试时容易出错
为什么不用 struct + NewXXX 而用闭包
当对象只暴露一两个行为、且内部状态极简(比如一个 int 或 string),闭包省去定义类型、字段、方法签名的样板。性能上几乎无差别,编译后都是函数指针 + 数据指针。
但要注意:闭包无法扩展方法,也不能实现接口(除非你把它包装进 struct)。所以它适合“一次性行为定制”,不适合需要后续加日志、监控、序列化等能力的对象。
本文共计1159个文字,预计阅读时间需要5分钟。
Go 语言中没有 class,但可以使用封装状态和行为来实现类似的功能。使用 struct 可以更轻量地实现方法。关键不在于模拟类,而是将具有相同功能的函数(如 func() int)打包成一个可复用的实例生成器。
常见错误是以为闭包必须返回 struct:其实它直接返回函数就行,比如计数器、配置化 HTTP 客户端、带默认超时的重试逻辑。
- 闭包捕获的是变量的引用,不是值——如果在循环里创建多个闭包,又共用同一个循环变量(如
i),最后所有闭包都看到同一个终值 - 想固定每次的值?用立即传参方式:
func(i int) func() { return func() { fmt.Println(i) } }(i) - 返回的函数类型要显式声明,别依赖类型推导,否则接口赋值或测试时容易出错
为什么不用 struct + NewXXX 而用闭包
当对象只暴露一两个行为、且内部状态极简(比如一个 int 或 string),闭包省去定义类型、字段、方法签名的样板。性能上几乎无差别,编译后都是函数指针 + 数据指针。
但要注意:闭包无法扩展方法,也不能实现接口(除非你把它包装进 struct)。所以它适合“一次性行为定制”,不适合需要后续加日志、监控、序列化等能力的对象。

