1006 lines
24 KiB
Go
1006 lines
24 KiB
Go
/*
|
||
04-closures.go - Go 语言闭包详解
|
||
|
||
学习目标:
|
||
1. 理解闭包的概念和原理
|
||
2. 掌握闭包的创建和使用
|
||
3. 学会闭包的实际应用场景
|
||
4. 了解闭包的内存管理
|
||
5. 掌握闭包的最佳实践
|
||
|
||
知识点:
|
||
- 闭包的定义和特性
|
||
- 词法作用域和变量捕获
|
||
- 闭包的生命周期
|
||
- 闭包与匿名函数的关系
|
||
- 闭包的实际应用模式
|
||
- 闭包的性能考虑
|
||
*/
|
||
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"math/rand"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println("=== Go 语言闭包详解 ===\n")
|
||
|
||
// 演示闭包的基本概念
|
||
demonstrateBasicClosures()
|
||
|
||
// 演示变量捕获
|
||
demonstrateVariableCapture()
|
||
|
||
// 演示闭包的状态保持
|
||
demonstrateStatefulClosures()
|
||
|
||
// 演示闭包作为返回值
|
||
demonstrateClosureReturns()
|
||
|
||
// 演示闭包的实际应用
|
||
demonstratePracticalApplications()
|
||
|
||
// 演示闭包的高级用法
|
||
demonstrateAdvancedClosureUsage()
|
||
|
||
// 演示闭包的注意事项
|
||
demonstrateClosureCaveats()
|
||
}
|
||
|
||
// demonstrateBasicClosures 演示闭包的基本概念
|
||
func demonstrateBasicClosures() {
|
||
fmt.Println("1. 闭包的基本概念:")
|
||
|
||
// 基本闭包示例
|
||
fmt.Printf(" 基本闭包示例:\n")
|
||
|
||
// 外部变量
|
||
message := "Hello from closure"
|
||
|
||
// 创建闭包 - 匿名函数访问外部变量
|
||
closure := func() {
|
||
fmt.Printf(" 闭包访问外部变量: %s\n", message)
|
||
}
|
||
|
||
// 调用闭包
|
||
closure()
|
||
|
||
// 修改外部变量
|
||
message = "Modified message"
|
||
closure() // 闭包看到修改后的值
|
||
|
||
// 闭包修改外部变量
|
||
fmt.Printf(" 闭包修改外部变量:\n")
|
||
counter := 0
|
||
|
||
increment := func() {
|
||
counter++
|
||
fmt.Printf(" 计数器值: %d\n", counter)
|
||
}
|
||
|
||
increment()
|
||
increment()
|
||
increment()
|
||
|
||
fmt.Printf(" 外部变量 counter 的最终值: %d\n", counter)
|
||
|
||
// 多个闭包共享变量
|
||
fmt.Printf(" 多个闭包共享变量:\n")
|
||
sharedValue := 10
|
||
|
||
add := func(n int) {
|
||
sharedValue += n
|
||
fmt.Printf(" add(%d): sharedValue = %d\n", n, sharedValue)
|
||
}
|
||
|
||
multiply := func(n int) {
|
||
sharedValue *= n
|
||
fmt.Printf(" multiply(%d): sharedValue = %d\n", n, sharedValue)
|
||
}
|
||
|
||
add(5) // 10 + 5 = 15
|
||
multiply(2) // 15 * 2 = 30
|
||
add(10) // 30 + 10 = 40
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateVariableCapture 演示变量捕获
|
||
func demonstrateVariableCapture() {
|
||
fmt.Println("2. 变量捕获:")
|
||
|
||
// 值捕获 vs 引用捕获
|
||
fmt.Printf(" 值类型变量的捕获:\n")
|
||
|
||
// 创建多个闭包,每个捕获不同的值
|
||
var functions []func()
|
||
|
||
for i := 0; i < 3; i++ {
|
||
// 错误的方式:所有闭包都会捕获同一个变量 i
|
||
functions = append(functions, func() {
|
||
fmt.Printf(" 错误方式 - i = %d\n", i)
|
||
})
|
||
}
|
||
|
||
fmt.Printf(" 错误的捕获方式(所有闭包都捕获同一个变量):\n")
|
||
for _, fn := range functions {
|
||
fn() // 都会打印 3,因为循环结束后 i = 3
|
||
}
|
||
|
||
// 正确的方式:为每个闭包创建独立的变量
|
||
functions = nil
|
||
for i := 0; i < 3; i++ {
|
||
i := i // 创建新的变量,捕获当前值
|
||
functions = append(functions, func() {
|
||
fmt.Printf(" 正确方式 - i = %d\n", i)
|
||
})
|
||
}
|
||
|
||
fmt.Printf(" 正确的捕获方式(每个闭包捕获独立的变量):\n")
|
||
for _, fn := range functions {
|
||
fn()
|
||
}
|
||
|
||
// 引用类型的捕获
|
||
fmt.Printf(" 引用类型变量的捕获:\n")
|
||
slice := []int{1, 2, 3}
|
||
|
||
modifySlice := func() {
|
||
slice[0] = 999
|
||
fmt.Printf(" 闭包修改切片: %v\n", slice)
|
||
}
|
||
|
||
fmt.Printf(" 原始切片: %v\n", slice)
|
||
modifySlice()
|
||
fmt.Printf(" 外部切片: %v\n", slice)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateStatefulClosures 演示闭包的状态保持
|
||
func demonstrateStatefulClosures() {
|
||
fmt.Println("3. 闭包的状态保持:")
|
||
|
||
// 计数器闭包
|
||
fmt.Printf(" 计数器闭包:\n")
|
||
counter1 := createCounter()
|
||
counter2 := createCounter()
|
||
|
||
fmt.Printf(" counter1: %d\n", counter1())
|
||
fmt.Printf(" counter1: %d\n", counter1())
|
||
fmt.Printf(" counter2: %d\n", counter2())
|
||
fmt.Printf(" counter1: %d\n", counter1())
|
||
fmt.Printf(" counter2: %d\n", counter2())
|
||
|
||
// 累加器闭包
|
||
fmt.Printf(" 累加器闭包:\n")
|
||
adder := createAdder(10) // 初始值为 10
|
||
|
||
fmt.Printf(" adder(5): %d\n", adder(5)) // 10 + 5 = 15
|
||
fmt.Printf(" adder(3): %d\n", adder(3)) // 15 + 3 = 18
|
||
fmt.Printf(" adder(-8): %d\n", adder(-8)) // 18 - 8 = 10
|
||
|
||
// 银行账户闭包
|
||
fmt.Printf(" 银行账户闭包:\n")
|
||
account := createBankAccount(1000.0)
|
||
|
||
fmt.Printf(" 初始余额: %.2f\n", account.getBalance())
|
||
fmt.Printf(" 存款 500: %.2f\n", account.deposit(500))
|
||
fmt.Printf(" 取款 200: %.2f\n", account.withdraw(200))
|
||
fmt.Printf(" 取款 2000: %.2f\n", account.withdraw(2000)) // 余额不足
|
||
|
||
// 历史记录闭包
|
||
fmt.Printf(" 历史记录闭包:\n")
|
||
history := createHistory()
|
||
|
||
history.add("用户登录")
|
||
history.add("查看订单")
|
||
history.add("添加商品到购物车")
|
||
history.add("结算订单")
|
||
|
||
fmt.Printf(" 历史记录:\n")
|
||
for i, record := range history.getAll() {
|
||
fmt.Printf(" %d. %s\n", i+1, record)
|
||
}
|
||
|
||
fmt.Printf(" 最近3条记录:\n")
|
||
for i, record := range history.getLast(3) {
|
||
fmt.Printf(" %d. %s\n", i+1, record)
|
||
}
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateClosureReturns 演示闭包作为返回值
|
||
func demonstrateClosureReturns() {
|
||
fmt.Println("4. 闭包作为返回值:")
|
||
|
||
// 数学运算闭包工厂
|
||
fmt.Printf(" 数学运算闭包工厂:\n")
|
||
|
||
add := createMathOperation("add")
|
||
multiply := createMathOperation("multiply")
|
||
power := createMathOperation("power")
|
||
|
||
fmt.Printf(" add(10, 5) = %.2f\n", add(10, 5))
|
||
fmt.Printf(" multiply(10, 5) = %.2f\n", multiply(10, 5))
|
||
fmt.Printf(" power(2, 8) = %.2f\n", power(2, 8))
|
||
|
||
// 验证器闭包工厂
|
||
fmt.Printf(" 验证器闭包工厂:\n")
|
||
|
||
emailValidator := createValidator("email")
|
||
phoneValidator := createValidator("phone")
|
||
ageValidator := createValidator("age")
|
||
|
||
testData := []struct {
|
||
validator func(string) bool
|
||
name string
|
||
values []string
|
||
}{
|
||
{emailValidator, "邮箱", []string{"user@example.com", "invalid-email", "test@domain.org"}},
|
||
{phoneValidator, "电话", []string{"138-1234-5678", "123", "186-9999-8888"}},
|
||
{ageValidator, "年龄", []string{"25", "abc", "150", "30"}},
|
||
}
|
||
|
||
for _, test := range testData {
|
||
fmt.Printf(" %s验证:\n", test.name)
|
||
for _, value := range test.values {
|
||
isValid := test.validator(value)
|
||
fmt.Printf(" \"%s\": %t\n", value, isValid)
|
||
}
|
||
}
|
||
|
||
// 配置闭包工厂
|
||
fmt.Printf(" 配置闭包工厂:\n")
|
||
|
||
devConfig := createConfigGetter("development")
|
||
prodConfig := createConfigGetter("production")
|
||
|
||
fmt.Printf(" 开发环境数据库: %s\n", devConfig("database"))
|
||
fmt.Printf(" 开发环境端口: %s\n", devConfig("port"))
|
||
fmt.Printf(" 生产环境数据库: %s\n", prodConfig("database"))
|
||
fmt.Printf(" 生产环境端口: %s\n", prodConfig("port"))
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstratePracticalApplications 演示闭包的实际应用
|
||
func demonstratePracticalApplications() {
|
||
fmt.Println("5. 闭包的实际应用:")
|
||
|
||
// 应用1: 事件处理器
|
||
fmt.Printf(" 应用1 - 事件处理器:\n")
|
||
|
||
button := createButton("提交按钮")
|
||
|
||
// 添加点击事件处理器
|
||
button.onClick(func() {
|
||
fmt.Printf(" 按钮被点击了!\n")
|
||
})
|
||
|
||
// 添加多个事件处理器
|
||
button.onClick(func() {
|
||
fmt.Printf(" 记录点击日志\n")
|
||
})
|
||
|
||
button.onClick(func() {
|
||
fmt.Printf(" 发送统计数据\n")
|
||
})
|
||
|
||
// 触发点击事件
|
||
button.click()
|
||
|
||
// 应用2: 缓存系统
|
||
fmt.Printf(" 应用2 - 缓存系统:\n")
|
||
|
||
cache := createCache()
|
||
|
||
// 设置缓存
|
||
cache.set("user:123", "Alice")
|
||
cache.set("user:456", "Bob")
|
||
|
||
// 获取缓存
|
||
if value, found := cache.get("user:123"); found {
|
||
fmt.Printf(" 缓存命中: user:123 = %s\n", value)
|
||
}
|
||
|
||
if value, found := cache.get("user:789"); found {
|
||
fmt.Printf(" 缓存命中: user:789 = %s\n", value)
|
||
} else {
|
||
fmt.Printf(" 缓存未命中: user:789\n")
|
||
}
|
||
|
||
// 显示缓存统计
|
||
stats := cache.getStats()
|
||
fmt.Printf(" 缓存统计: 命中 %d 次,未命中 %d 次\n", stats.hits, stats.misses)
|
||
|
||
// 应用3: 中间件模式
|
||
fmt.Printf(" 应用3 - 中间件模式:\n")
|
||
|
||
// 创建处理器
|
||
handler := func(request string) string {
|
||
return fmt.Sprintf("处理请求: %s", request)
|
||
}
|
||
|
||
// 应用中间件
|
||
withLogging := loggingMiddleware(handler)
|
||
withAuth := authMiddleware(withLogging)
|
||
withRateLimit := rateLimitMiddleware(withAuth)
|
||
|
||
// 处理请求
|
||
result := withRateLimit("GET /api/users")
|
||
fmt.Printf(" 最终结果: %s\n", result)
|
||
|
||
// 应用4: 函数式编程
|
||
fmt.Printf(" 应用4 - 函数式编程:\n")
|
||
|
||
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||
|
||
// 使用闭包进行函数式操作
|
||
evenNumbers := filter(numbers, func(n int) bool { return n%2 == 0 })
|
||
fmt.Printf(" 偶数: %v\n", evenNumbers)
|
||
|
||
squares := mapInts(numbers, func(n int) int { return n * n })
|
||
fmt.Printf(" 平方: %v\n", squares)
|
||
|
||
sum := reduce(numbers, 0, func(acc, n int) int { return acc + n })
|
||
fmt.Printf(" 求和: %d\n", sum)
|
||
|
||
// 应用5: 延迟执行
|
||
fmt.Printf(" 应用5 - 延迟执行:\n")
|
||
|
||
// 创建延迟任务
|
||
task1 := createDelayedTask("任务1", func() {
|
||
fmt.Printf(" 执行任务1: 发送邮件\n")
|
||
})
|
||
|
||
task2 := createDelayedTask("任务2", func() {
|
||
fmt.Printf(" 执行任务2: 清理缓存\n")
|
||
})
|
||
|
||
// 延迟执行
|
||
fmt.Printf(" 创建延迟任务...\n")
|
||
time.Sleep(100 * time.Millisecond)
|
||
|
||
task1.execute()
|
||
task2.execute()
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateAdvancedClosureUsage 演示闭包的高级用法
|
||
func demonstrateAdvancedClosureUsage() {
|
||
fmt.Println("6. 闭包的高级用法:")
|
||
|
||
// 高级用法1: 柯里化
|
||
fmt.Printf(" 高级用法1 - 柯里化:\n")
|
||
|
||
// 创建柯里化的加法函数
|
||
curriedAdd := curry(func(a, b, c int) int {
|
||
return a + b + c
|
||
})
|
||
|
||
// 部分应用
|
||
add5 := curriedAdd(5)
|
||
add5And3 := add5(3)
|
||
|
||
result := add5And3(2) // 5 + 3 + 2 = 10
|
||
fmt.Printf(" 柯里化结果: 5 + 3 + 2 = %d\n", result)
|
||
|
||
// 高级用法2: 记忆化
|
||
fmt.Printf(" 高级用法2 - 记忆化:\n")
|
||
|
||
// 创建记忆化的斐波那契函数
|
||
memoFib := memoize(fibonacci)
|
||
|
||
fmt.Printf(" 计算斐波那契数列:\n")
|
||
for i := 0; i <= 10; i++ {
|
||
result := memoFib(i)
|
||
fmt.Printf(" fib(%d) = %d\n", i, result)
|
||
}
|
||
|
||
// 高级用法3: 装饰器模式
|
||
fmt.Printf(" 高级用法3 - 装饰器模式:\n")
|
||
|
||
// 原始函数
|
||
slowFunction := func(n int) int {
|
||
time.Sleep(10 * time.Millisecond) // 模拟慢操作
|
||
return n * n
|
||
}
|
||
|
||
// 应用装饰器
|
||
timedFunction := withTiming(slowFunction)
|
||
cachedFunction := withCaching(timedFunction)
|
||
|
||
fmt.Printf(" 第一次调用:\n")
|
||
result1 := cachedFunction(5)
|
||
fmt.Printf(" 结果: %d\n", result1)
|
||
|
||
fmt.Printf(" 第二次调用(应该使用缓存):\n")
|
||
result2 := cachedFunction(5)
|
||
fmt.Printf(" 结果: %d\n", result2)
|
||
|
||
// 高级用法4: 状态机
|
||
fmt.Printf(" 高级用法4 - 状态机:\n")
|
||
|
||
fsm := createStateMachine()
|
||
|
||
fmt.Printf(" 当前状态: %s\n", fsm.getState())
|
||
fsm.start()
|
||
fmt.Printf(" 当前状态: %s\n", fsm.getState())
|
||
fsm.pause()
|
||
fmt.Printf(" 当前状态: %s\n", fsm.getState())
|
||
fsm.resume()
|
||
fmt.Printf(" 当前状态: %s\n", fsm.getState())
|
||
fsm.stop()
|
||
fmt.Printf(" 当前状态: %s\n", fsm.getState())
|
||
|
||
// 高级用法5: 观察者模式
|
||
fmt.Printf(" 高级用法5 - 观察者模式:\n")
|
||
|
||
subject := createSubject()
|
||
|
||
// 添加观察者
|
||
subject.subscribe(func(data interface{}) {
|
||
fmt.Printf(" 观察者1收到数据: %v\n", data)
|
||
})
|
||
|
||
subject.subscribe(func(data interface{}) {
|
||
fmt.Printf(" 观察者2收到数据: %v\n", data)
|
||
})
|
||
|
||
// 通知观察者
|
||
subject.notify("Hello, Observers!")
|
||
subject.notify(42)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateClosureCaveats 演示闭包的注意事项
|
||
func demonstrateClosureCaveats() {
|
||
fmt.Println("7. 闭包的注意事项:")
|
||
|
||
// 注意事项1: 循环变量捕获
|
||
fmt.Printf(" 注意事项1 - 循环变量捕获:\n")
|
||
fmt.Printf(" 这是一个常见的陷阱,前面已经演示过\n")
|
||
|
||
// 注意事项2: 内存泄漏
|
||
fmt.Printf(" 注意事项2 - 内存泄漏风险:\n")
|
||
fmt.Printf(" 闭包会保持对外部变量的引用,可能导致内存泄漏\n")
|
||
|
||
// 创建一个可能导致内存泄漏的示例
|
||
largeData := make([]int, 1000000) // 大数组
|
||
for i := range largeData {
|
||
largeData[i] = i
|
||
}
|
||
|
||
// 闭包只使用数组的第一个元素,但会保持整个数组的引用
|
||
getClosure := func() func() int {
|
||
return func() int {
|
||
return largeData[0] // 只使用第一个元素
|
||
}
|
||
}
|
||
|
||
closure := getClosure()
|
||
fmt.Printf(" 闭包结果: %d\n", closure())
|
||
fmt.Printf(" 注意: 闭包保持了整个大数组的引用\n")
|
||
|
||
// 更好的做法:只捕获需要的数据
|
||
getBetterClosure := func() func() int {
|
||
firstElement := largeData[0] // 只捕获需要的值
|
||
return func() int {
|
||
return firstElement
|
||
}
|
||
}
|
||
|
||
betterClosure := getBetterClosure()
|
||
fmt.Printf(" 改进的闭包结果: %d\n", betterClosure())
|
||
fmt.Printf(" 改进: 只捕获需要的值,不保持大数组引用\n")
|
||
|
||
// 注意事项3: 性能考虑
|
||
fmt.Printf(" 注意事项3 - 性能考虑:\n")
|
||
fmt.Printf(" 闭包的创建和调用有一定的性能开销\n")
|
||
|
||
// 测量闭包 vs 普通函数的性能
|
||
normalFunc := func(x int) int { return x * 2 }
|
||
|
||
multiplier := 2
|
||
closureFunc := func(x int) int { return x * multiplier }
|
||
|
||
// 简单的性能比较(实际测试需要更严格的基准测试)
|
||
start := time.Now()
|
||
for i := 0; i < 1000000; i++ {
|
||
normalFunc(i)
|
||
}
|
||
normalTime := time.Since(start)
|
||
|
||
start = time.Now()
|
||
for i := 0; i < 1000000; i++ {
|
||
closureFunc(i)
|
||
}
|
||
closureTime := time.Since(start)
|
||
|
||
fmt.Printf(" 普通函数耗时: %v\n", normalTime)
|
||
fmt.Printf(" 闭包函数耗时: %v\n", closureTime)
|
||
|
||
// 最佳实践
|
||
fmt.Printf(" 最佳实践:\n")
|
||
fmt.Printf(" 1. 避免在循环中直接使用循环变量创建闭包\n")
|
||
fmt.Printf(" 2. 只捕获必要的变量,避免捕获大对象\n")
|
||
fmt.Printf(" 3. 注意闭包的生命周期,避免内存泄漏\n")
|
||
fmt.Printf(" 4. 在性能敏感的代码中谨慎使用闭包\n")
|
||
fmt.Printf(" 5. 使用闭包实现优雅的设计模式\n")
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// ========== 函数定义 ==========
|
||
|
||
// 基本闭包函数
|
||
func createCounter() func() int {
|
||
count := 0
|
||
return func() int {
|
||
count++
|
||
return count
|
||
}
|
||
}
|
||
|
||
func createAdder(initial int) func(int) int {
|
||
sum := initial
|
||
return func(n int) int {
|
||
sum += n
|
||
return sum
|
||
}
|
||
}
|
||
|
||
// 银行账户闭包
|
||
type BankAccount struct {
|
||
getBalance func() float64
|
||
deposit func(float64) float64
|
||
withdraw func(float64) float64
|
||
}
|
||
|
||
func createBankAccount(initialBalance float64) BankAccount {
|
||
balance := initialBalance
|
||
|
||
return BankAccount{
|
||
getBalance: func() float64 {
|
||
return balance
|
||
},
|
||
deposit: func(amount float64) float64 {
|
||
if amount > 0 {
|
||
balance += amount
|
||
}
|
||
return balance
|
||
},
|
||
withdraw: func(amount float64) float64 {
|
||
if amount > 0 && amount <= balance {
|
||
balance -= amount
|
||
}
|
||
return balance
|
||
},
|
||
}
|
||
}
|
||
|
||
// 历史记录闭包
|
||
type History struct {
|
||
add func(string)
|
||
getAll func() []string
|
||
getLast func(int) []string
|
||
}
|
||
|
||
func createHistory() History {
|
||
var records []string
|
||
|
||
return History{
|
||
add: func(record string) {
|
||
records = append(records, record)
|
||
},
|
||
getAll: func() []string {
|
||
result := make([]string, len(records))
|
||
copy(result, records)
|
||
return result
|
||
},
|
||
getLast: func(n int) []string {
|
||
if n >= len(records) {
|
||
result := make([]string, len(records))
|
||
copy(result, records)
|
||
return result
|
||
}
|
||
result := make([]string, n)
|
||
copy(result, records[len(records)-n:])
|
||
return result
|
||
},
|
||
}
|
||
}
|
||
|
||
// 数学运算闭包工厂
|
||
func createMathOperation(operation string) func(float64, float64) float64 {
|
||
switch operation {
|
||
case "add":
|
||
return func(a, b float64) float64 { return a + b }
|
||
case "subtract":
|
||
return func(a, b float64) float64 { return a - b }
|
||
case "multiply":
|
||
return func(a, b float64) float64 { return a * b }
|
||
case "divide":
|
||
return func(a, b float64) float64 {
|
||
if b != 0 {
|
||
return a / b
|
||
}
|
||
return 0
|
||
}
|
||
case "power":
|
||
return func(a, b float64) float64 {
|
||
result := 1.0
|
||
for i := 0; i < int(b); i++ {
|
||
result *= a
|
||
}
|
||
return result
|
||
}
|
||
default:
|
||
return func(a, b float64) float64 { return 0 }
|
||
}
|
||
}
|
||
|
||
// 验证器闭包工厂
|
||
func createValidator(validationType string) func(string) bool {
|
||
switch validationType {
|
||
case "email":
|
||
return func(email string) bool {
|
||
return len(email) > 0 &&
|
||
strings.Contains(email, "@") &&
|
||
strings.Contains(email, ".")
|
||
}
|
||
case "phone":
|
||
return func(phone string) bool {
|
||
return len(phone) >= 10 && strings.Contains(phone, "-")
|
||
}
|
||
case "age":
|
||
return func(ageStr string) bool {
|
||
// 简单验证:只检查是否为数字
|
||
for _, char := range ageStr {
|
||
if char < '0' || char > '9' {
|
||
return false
|
||
}
|
||
}
|
||
return len(ageStr) > 0
|
||
}
|
||
default:
|
||
return func(string) bool { return false }
|
||
}
|
||
}
|
||
|
||
// 配置闭包工厂
|
||
func createConfigGetter(environment string) func(string) string {
|
||
configs := map[string]map[string]string{
|
||
"development": {
|
||
"database": "localhost:5432",
|
||
"port": "8080",
|
||
"debug": "true",
|
||
},
|
||
"production": {
|
||
"database": "prod-db:5432",
|
||
"port": "80",
|
||
"debug": "false",
|
||
},
|
||
}
|
||
|
||
envConfig := configs[environment]
|
||
|
||
return func(key string) string {
|
||
if value, exists := envConfig[key]; exists {
|
||
return value
|
||
}
|
||
return ""
|
||
}
|
||
}
|
||
|
||
// 事件处理器
|
||
type Button struct {
|
||
name string
|
||
handlers []func()
|
||
}
|
||
|
||
func createButton(name string) *Button {
|
||
return &Button{name: name}
|
||
}
|
||
|
||
func (b *Button) onClick(handler func()) {
|
||
b.handlers = append(b.handlers, handler)
|
||
}
|
||
|
||
func (b *Button) click() {
|
||
fmt.Printf(" 点击按钮: %s\n", b.name)
|
||
for _, handler := range b.handlers {
|
||
handler()
|
||
}
|
||
}
|
||
|
||
// 缓存系统
|
||
type Cache struct {
|
||
set func(string, string)
|
||
get func(string) (string, bool)
|
||
getStats func() struct{ hits, misses int }
|
||
}
|
||
|
||
func createCache() Cache {
|
||
data := make(map[string]string)
|
||
hits := 0
|
||
misses := 0
|
||
|
||
return Cache{
|
||
set: func(key, value string) {
|
||
data[key] = value
|
||
},
|
||
get: func(key string) (string, bool) {
|
||
if value, exists := data[key]; exists {
|
||
hits++
|
||
return value, true
|
||
}
|
||
misses++
|
||
return "", false
|
||
},
|
||
getStats: func() struct{ hits, misses int } {
|
||
return struct{ hits, misses int }{hits, misses}
|
||
},
|
||
}
|
||
}
|
||
|
||
// 中间件模式
|
||
func loggingMiddleware(next func(string) string) func(string) string {
|
||
return func(request string) string {
|
||
fmt.Printf(" [LOG] 处理请求: %s\n", request)
|
||
result := next(request)
|
||
fmt.Printf(" [LOG] 请求完成: %s\n", request)
|
||
return result
|
||
}
|
||
}
|
||
|
||
func authMiddleware(next func(string) string) func(string) string {
|
||
return func(request string) string {
|
||
fmt.Printf(" [AUTH] 验证请求: %s\n", request)
|
||
// 模拟认证
|
||
if strings.Contains(request, "GET") {
|
||
return next(request)
|
||
}
|
||
return "认证失败"
|
||
}
|
||
}
|
||
|
||
func rateLimitMiddleware(next func(string) string) func(string) string {
|
||
requestCount := 0
|
||
return func(request string) string {
|
||
requestCount++
|
||
fmt.Printf(" [RATE] 请求计数: %d\n", requestCount)
|
||
if requestCount > 10 {
|
||
return "请求过于频繁"
|
||
}
|
||
return next(request)
|
||
}
|
||
}
|
||
|
||
// 函数式编程辅助函数
|
||
func filter(slice []int, predicate func(int) bool) []int {
|
||
var result []int
|
||
for _, item := range slice {
|
||
if predicate(item) {
|
||
result = append(result, item)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
func mapInts(slice []int, mapper func(int) int) []int {
|
||
result := make([]int, len(slice))
|
||
for i, item := range slice {
|
||
result[i] = mapper(item)
|
||
}
|
||
return result
|
||
}
|
||
|
||
func reduce(slice []int, initial int, reducer func(int, int) int) int {
|
||
result := initial
|
||
for _, item := range slice {
|
||
result = reducer(result, item)
|
||
}
|
||
return result
|
||
}
|
||
|
||
// 延迟执行
|
||
type DelayedTask struct {
|
||
name string
|
||
task func()
|
||
execute func()
|
||
}
|
||
|
||
func createDelayedTask(name string, task func()) DelayedTask {
|
||
return DelayedTask{
|
||
name: name,
|
||
task: task,
|
||
execute: func() {
|
||
fmt.Printf(" 准备执行延迟任务: %s\n", name)
|
||
task()
|
||
},
|
||
}
|
||
}
|
||
|
||
// 柯里化
|
||
func curry(fn func(int, int, int) int) func(int) func(int) func(int) int {
|
||
return func(a int) func(int) func(int) int {
|
||
return func(b int) func(int) int {
|
||
return func(c int) int {
|
||
return fn(a, b, c)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 记忆化
|
||
func memoize(fn func(int) int) func(int) int {
|
||
cache := make(map[int]int)
|
||
return func(n int) int {
|
||
if result, exists := cache[n]; exists {
|
||
return result
|
||
}
|
||
result := fn(n)
|
||
cache[n] = result
|
||
return result
|
||
}
|
||
}
|
||
|
||
func fibonacci(n int) int {
|
||
if n <= 1 {
|
||
return n
|
||
}
|
||
return fibonacci(n-1) + fibonacci(n-2)
|
||
}
|
||
|
||
// 装饰器模式
|
||
func withTiming(fn func(int) int) func(int) int {
|
||
return func(n int) int {
|
||
start := time.Now()
|
||
result := fn(n)
|
||
duration := time.Since(start)
|
||
fmt.Printf(" 函数执行耗时: %v\n", duration)
|
||
return result
|
||
}
|
||
}
|
||
|
||
func withCaching(fn func(int) int) func(int) int {
|
||
cache := make(map[int]int)
|
||
return func(n int) int {
|
||
if result, exists := cache[n]; exists {
|
||
fmt.Printf(" 使用缓存结果\n")
|
||
return result
|
||
}
|
||
fmt.Printf(" 计算新结果\n")
|
||
result := fn(n)
|
||
cache[n] = result
|
||
return result
|
||
}
|
||
}
|
||
|
||
// 状态机
|
||
type StateMachine struct {
|
||
getState func() string
|
||
start func()
|
||
pause func()
|
||
resume func()
|
||
stop func()
|
||
}
|
||
|
||
func createStateMachine() StateMachine {
|
||
state := "idle"
|
||
|
||
return StateMachine{
|
||
getState: func() string {
|
||
return state
|
||
},
|
||
start: func() {
|
||
if state == "idle" {
|
||
state = "running"
|
||
}
|
||
},
|
||
pause: func() {
|
||
if state == "running" {
|
||
state = "paused"
|
||
}
|
||
},
|
||
resume: func() {
|
||
if state == "paused" {
|
||
state = "running"
|
||
}
|
||
},
|
||
stop: func() {
|
||
if state == "running" || state == "paused" {
|
||
state = "idle"
|
||
}
|
||
},
|
||
}
|
||
}
|
||
|
||
// 观察者模式
|
||
type Subject struct {
|
||
subscribe func(func(interface{}))
|
||
notify func(interface{})
|
||
}
|
||
|
||
func createSubject() Subject {
|
||
var observers []func(interface{})
|
||
|
||
return Subject{
|
||
subscribe: func(observer func(interface{})) {
|
||
observers = append(observers, observer)
|
||
},
|
||
notify: func(data interface{}) {
|
||
for _, observer := range observers {
|
||
observer(data)
|
||
}
|
||
},
|
||
}
|
||
}
|
||
|
||
func init() {
|
||
rand.Seed(time.Now().UnixNano())
|
||
}
|
||
|
||
/*
|
||
运行这个程序:
|
||
go run 04-closures.go
|
||
|
||
学习要点:
|
||
1. 闭包是函数和其词法环境的组合
|
||
2. 闭包可以访问和修改外部作用域的变量
|
||
3. 闭包可以保持状态,实现数据封装
|
||
4. 闭包常用于回调函数、事件处理、函数式编程
|
||
5. 需要注意循环变量捕获和内存泄漏问题
|
||
|
||
闭包的特性:
|
||
1. 词法作用域:闭包可以访问定义时的作用域
|
||
2. 变量捕获:闭包会捕获外部变量的引用
|
||
3. 状态保持:闭包可以在多次调用间保持状态
|
||
4. 延迟执行:闭包可以延迟执行代码
|
||
|
||
常见应用场景:
|
||
1. 事件处理和回调函数
|
||
2. 函数式编程(map、filter、reduce)
|
||
3. 中间件和装饰器模式
|
||
4. 状态管理和数据封装
|
||
5. 配置和选项处理
|
||
6. 缓存和记忆化
|
||
7. 延迟执行和任务调度
|
||
|
||
设计模式:
|
||
1. 工厂模式:返回配置好的闭包
|
||
2. 装饰器模式:包装函数添加功能
|
||
3. 观察者模式:事件处理和通知
|
||
4. 状态机模式:状态管理
|
||
5. 策略模式:动态选择算法
|
||
|
||
最佳实践:
|
||
1. 避免在循环中直接捕获循环变量
|
||
2. 只捕获必要的变量,避免内存泄漏
|
||
3. 合理使用闭包实现优雅的API设计
|
||
4. 注意闭包的性能开销
|
||
5. 使用闭包实现函数式编程风格
|
||
|
||
注意事项:
|
||
1. 循环变量捕获陷阱
|
||
2. 内存泄漏风险
|
||
3. 性能开销
|
||
4. 调试困难
|
||
5. 代码可读性
|
||
|
||
高级用法:
|
||
1. 柯里化和部分应用
|
||
2. 记忆化优化
|
||
3. 函数组合和管道
|
||
4. 异步编程模式
|
||
5. 依赖注入
|
||
*/ |