Lua 如果在声明变量的同一语句中声明,则对变量的闭包引用失败
Lua closure reference to variable fails if declared in the same statement declaring the variable
这是一个关于 Lua 中闭包的问题。我在尝试按如下方式创建对象注册器对象时偶然发现了一个问题(和解决方法):
tracker = {
objList = {},
myRegister = function(self, obj)
table.insert(self.objList, obj)
return "hello"
end,
myInit = function(self)
local i, obj
for i, obj in ipairs(self.objList) do
obj:init()
end
end,
}
-- Note: As written, this does *not* work.
-- It *will* work if I separate the line into two parts as follows:
-- local myvar
-- myvar = tracker:myRegister({
local myvar = tracker:myRegister({
init = function(self)
-- This will generate an error complaining that myvar
-- is a global variable with a "nil" value
print("myvar = " .. myvar)
end,
})
tracker:myInit()
似乎如果我在创建闭包的同一语句中声明局部变量 "myvar",则无法从闭包访问局部变量。但是,如果我只是分配给一个已经存在的局部变量,那么该变量可以从闭包中访问。
显然,我知道如何解决这个问题:只需单独声明 myvar。
然而,我的问题是:为什么这是必要的?这是设计使然,还是编译器 and/or 虚拟机中的错误?如果是设计使然,它在哪里记录?我对这种行为是否有其他影响以及可能是什么特别感兴趣,我希望文档(再次假设这是预期的行为)将对此有所说明。
是的,这是预期的行为。
它记录在 Lua 手册 §3.5 – Visibility Rules
此功能允许您编写以下代码:
print"Beginning of log"
do
local print =
function(...)
print(os.date"%T", ...) -- Here you're invoking global "print"
end
-- inside this do-end block "print" is automatically adding current time
print"Some event"
print"Another event"
end
print"End of log"
换句话说,在创建阴影对象的同时,原始对象仍然可以访问。
这很有用。
这是一个关于 Lua 中闭包的问题。我在尝试按如下方式创建对象注册器对象时偶然发现了一个问题(和解决方法):
tracker = {
objList = {},
myRegister = function(self, obj)
table.insert(self.objList, obj)
return "hello"
end,
myInit = function(self)
local i, obj
for i, obj in ipairs(self.objList) do
obj:init()
end
end,
}
-- Note: As written, this does *not* work.
-- It *will* work if I separate the line into two parts as follows:
-- local myvar
-- myvar = tracker:myRegister({
local myvar = tracker:myRegister({
init = function(self)
-- This will generate an error complaining that myvar
-- is a global variable with a "nil" value
print("myvar = " .. myvar)
end,
})
tracker:myInit()
似乎如果我在创建闭包的同一语句中声明局部变量 "myvar",则无法从闭包访问局部变量。但是,如果我只是分配给一个已经存在的局部变量,那么该变量可以从闭包中访问。
显然,我知道如何解决这个问题:只需单独声明 myvar。
然而,我的问题是:为什么这是必要的?这是设计使然,还是编译器 and/or 虚拟机中的错误?如果是设计使然,它在哪里记录?我对这种行为是否有其他影响以及可能是什么特别感兴趣,我希望文档(再次假设这是预期的行为)将对此有所说明。
是的,这是预期的行为。
它记录在 Lua 手册 §3.5 – Visibility Rules
此功能允许您编写以下代码:
print"Beginning of log"
do
local print =
function(...)
print(os.date"%T", ...) -- Here you're invoking global "print"
end
-- inside this do-end block "print" is automatically adding current time
print"Some event"
print"Another event"
end
print"End of log"
换句话说,在创建阴影对象的同时,原始对象仍然可以访问。
这很有用。