闭包 #
一、闭包概念 #
1.1 什么是闭包 #
闭包是一个函数,它可以捕获并访问其外部作用域中的变量。
julia
function outer()
x = 10
function inner()
x + 1
end
return inner
end
f = outer()
f()
1.2 变量捕获 #
闭包捕获的是变量本身,而不是变量的值:
julia
function make_counter()
count = 0
() -> (count += 1)
end
counter = make_counter()
counter()
counter()
counter()
二、闭包应用 #
2.1 计数器 #
julia
function make_counter(start=0)
count = start
() -> (count += 1)
end
counter = make_counter()
counter()
counter()
counter2 = make_counter(100)
counter2()
2.2 累加器 #
julia
function make_accumulator(initial=0)
total = initial
x -> (total += x)
end
acc = make_accumulator()
acc(10)
acc(5)
acc(3)
2.3 乘法器工厂 #
julia
function make_multiplier(n)
x -> x * n
end
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
times_3(10)
times_5(10)
2.4 配置函数 #
julia
function make_greeter(greeting, punctuation="!")
name -> println("$greeting, $name$punctuation")
end
say_hello = make_greeter("Hello")
say_hi = make_greeter("Hi", "?")
say_hello("Julia")
say_hi("Julia")
三、闭包与状态 #
3.1 私有状态 #
闭包可以创建私有状态:
julia
function make_bank_account(initial=0)
balance = initial
(operation, amount=0) -> begin
if operation == :deposit
balance += amount
elseif operation == :withdraw
if amount <= balance
balance -= amount
else
return "Insufficient funds"
end
elseif operation == :balance
return balance
else
return "Unknown operation"
end
return balance
end
end
account = make_bank_account(100)
account(:deposit, 50)
account(:withdraw, 30)
account(:balance)
3.2 多函数状态共享 #
julia
function make_counter_with_methods()
count = 0
(
increment = () -> (count += 1),
decrement = () -> (count -= 1),
get = () -> count,
reset = () -> (count = 0)
)
end
counter = make_counter_with_methods()
counter.increment()
counter.increment()
counter.get()
counter.decrement()
counter.get()
counter.reset()
counter.get()
四、闭包与循环 #
4.1 循环中的闭包 #
julia
functions = []
for i in 1:3
push!(functions, () -> i)
end
for f in functions
println(f())
end
4.2 捕获问题 #
julia
functions = []
for i in 1:3
push!(functions, let i = i
() -> i
end)
end
for f in functions
println(f())
end
4.3 使用let创建新作用域 #
julia
function make_functions()
functions = []
for i in 1:3
let i = i
push!(functions, () -> i)
end
end
return functions
end
funcs = make_functions()
[f() for f in funcs]
五、闭包与性能 #
5.1 类型稳定性 #
闭包捕获的变量可能导致类型不稳定:
julia
function make_adder_unstable()
x = 0
y -> begin
x = y
x + 1
end
end
5.2 类型注解 #
使用类型注解提高性能:
julia
function make_adder_stable()
x::Int = 0
y::Int -> begin
x = y
x + 1
end
end
六、实践练习 #
6.1 练习1:缓存函数 #
julia
function memoize(f)
cache = Dict{Tuple, Any}()
function(args...)
key = args
if !haskey(cache, key)
cache[key] = f(args...)
end
return cache[key]
end
end
fib = memoize(function(n)
n <= 1 ? n : fib(n-1) + fib(n-2)
end)
fib(40)
6.2 练习2:节流函数 #
julia
function throttle(f, interval)
last_called = Ref(time() - interval)
function(args...)
current = time()
if current - last_called[] >= interval
last_called[] = current
return f(args...)
end
return nothing
end
end
throttled_print = throttle(println, 1.0)
throttled_print("Hello")
throttled_print("World")
sleep(1.0)
throttled_print("Julia")
6.3 练习3:事件发射器 #
julia
function make_emitter()
listeners = []
(
on = (callback) -> push!(listeners, callback),
emit = (event) -> foreach(f -> f(event), listeners),
off = (callback) -> filter!(f -> f !== callback, listeners)
)
end
emitter = make_emitter()
emitter.on(x -> println("Listener 1: $x"))
emitter.on(x -> println("Listener 2: $x"))
emitter.emit("Hello")
6.4 练习4:状态机 #
julia
function make_state_machine(initial_state, transitions)
state = Ref(initial_state)
function transition(event)
current = state[]
if haskey(transitions, (current, event))
state[] = transitions[(current, event)]
return state[]
end
return nothing
end
() -> state[]
end
transitions = Dict(
(:off, :switch) => :on,
(:on, :switch) => :off
)
light = make_state_machine(:off, transitions)
light()
七、总结 #
本章我们学习了:
- 闭包概念:捕获外部变量
- 闭包应用:计数器、累加器、工厂函数
- 状态管理:私有状态和多函数共享
- 循环闭包:let块解决捕获问题
- 性能考虑:类型稳定性
接下来让我们学习Julia的类型系统!
最后更新:2026-03-27