Lua与_ENV的奇怪行为
有人能解释为什么Lua5.3.5会这样做吗Lua与_ENV的奇怪行为,lua,Lua,有人能解释为什么Lua5.3.5会这样做吗 a="global" local b="local" function problem(_ENV) a="fn_a" b="fn_b" end problem{} print(_VERSION) print("a",a) print("b",b) --[[ https://www.lua.org/cgi-bin/demo output: Lua 5.3 a global b fn_b ]] 为什么局部变量
a="global"
local b="local"
function problem(_ENV)
a="fn_a"
b="fn_b"
end
problem{}
print(_VERSION)
print("a",a)
print("b",b)
--[[ https://www.lua.org/cgi-bin/demo output:
Lua 5.3
a global
b fn_b
]]
为什么局部变量可以在_ENV更改后更改?是bug还是功能?您正在使用以下代码创建:
local b="local"
function problem(_ENV)
b="fn_b"
end
在解析函数的过程中,解释器检测到,该函数引用从函数内部可见的一个包围范围中的局部变量,从而直接链接它。在
\u ENV
中查找全局变量之前,先访问局部变量。如果将local b=“local”
放在函数定义之后,则函数调用不会对其进行更改 Q:如何消除所有的上升值?A:
a="global"
local b="local"
-- load() actually eliminates all upvalues :-)
no_problem = assert(load[[
return function (_ENV)
a="fn_a"
b="fn_b"
end
]])()
no_problem{}
print(_VERSION)
print("a",a) --> a global
print("b",b) --> b local
粗略地说,本地人优先于高于全球人的价值观;它们位于块(编译单元)中。因此,这是一个特性。如果您试图使用用户提供的代码,请进行研究。沙盒也有同样的问题本地b a=“全局”b=“本地”函数fn()a=“fn_a”b=“fn_b”结束打印(a,b)运行沙盒(Sandbox_env,fn)打印(a,b)如何消除所有upvalues?@SergeyKovalev upvalues不能“消除”。只是不引用它们。它只在加载块内对upvalue进行初始化,但如果我从加载块调用其他函数,其行为将是相同的。它可以修改父状态。因此,只有io.popen或创建不同lua上下文的特殊c函数才能真正分离代码。@SergeyKovalev-您可以在另一个
load
块中使用load
block;-)