闭包之间共享上值
了解多个闭包共享同一个上值及其变更带来的影响。
闭包之间共享上值 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
共享同一个上值
在同一作用域中定义的两个闭包可以共享完全相同的上值单元。其中一个闭包进行的修改,另一个闭包也能看到。
local function makeGetterSetter()
local value = 0
local function get() return value end
local function set(v) value = v end
return get, set
end
local get, set = makeGetterSetter()
set(42)
print(get()) -- 42为什么会发生共享
Lua 不会为每个闭包复制上值。在同一代码块中创建、并指向同一个局部变量的所有闭包,都会共享一个上值单元。
通过共享上值实现观察者模式
共享上值可以充当多个闭包之间的消息总线。
local count = 0
local inc = function() count = count + 1 end
local dec = function() count = count - 1 end
local get = function() return count end
inc(); inc(); dec()
print(get()) -- 1循环变量的陷阱
在 numeric for 循环中,每次迭代都会创建一个新的局部循环变量,因此闭包捕获的是彼此独立的上值。
local fns = {}
for i = 1, 3 do
fns[i] = function() return i end
end
print(fns[1](), fns[2](), fns[3]()) -- 1 2 3 (each closure has its own i)while 循环变量的陷阱
在 while 循环中,如果闭包捕获的是一个会发生变化的变量,那么所有闭包都会共享同一个上值,并看到最终值。
local fns = {}
local i = 0
while i < 3 do
i = i + 1
fns[i] = function() return i end -- all share same i!
end
print(fns[1]()) -- 3 (not 1!)捕获新的局部变量
要在 while 循环中捕获彼此独立的值,请在循环体内引入新的局部变量。
local fns = {}
local i = 0
while i < 3 do
i = i + 1
local ci = i -- new local per iteration
fns[i] = function() return ci end
end
print(fns[1]()) -- 1, fns[2]() == 2共享状态模块模式
模块可以通过上值,让多个函数共享一个私有状态表。
local function makeStack()
local data = {}
return {
push = function(v) data[#data+1] = v end,
pop = function() local v = data[#data]; data[#data]=nil; return v end,
size = function() return #data end,
}
end别名与修改
请注意:所有引用同一个上值的闭包都会立即看到相同的修改。这种机制很强大,但也可能造成意外的耦合。
上值标识
debug.upvalueid(f, n) 返回函数 f 第 n 个上值的唯一标识。具有相同上值 ID 的两个闭包共享同一个单元。
debug.upvaluejoin
debug.upvaluejoin(f1, n1, f2, n2) 让 f1 的第 n 个上值与 f2 的第 n 个上值共享同一个单元。这是用于调试的底层工具。
实用模式
- 共享私有变量的获取器/设置器组合。
- 通过多个闭包暴露重置功能的事件计数器。
- 多个 API 函数共享的模块状态。
共享上值问题
在同一作用域中创建了两个闭包 get 和 set,它们都捕获了 value。如果调用 set(99),get() 会返回什么?
回顾:共享上值
同一作用域中的闭包会共享上值单元。所有共享闭包都会立即看到修改后的值。这是 Lua 中实现封装和模块状态的基础。
常见问题解答
「闭包之间共享上值」课时是免费的吗?
是的 — 「闭包之间共享上值」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「闭包之间共享上值」这节课中我会学到什么?
了解多个闭包共享同一个上值及其变更带来的影响。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「闭包之间共享上值」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。