Lua:函数内的加载字符串似乎不起作用?

Lua: loadstring inside a function appearing to not work?

在一个函数(doloadstring)中,我注意到 loadstring,即使传递了正确的字符串,也不会修改函数变量。给出了什么?

我的猜测是 x 是局部变量而 loadstring 仅具有全局作用域?`

print('this works as I expect')
x = 0
loadstring('x = 1')()
print(x)

print('this does not')
function doloadstring(x, s)
    print(x)
    loadstring(s)() -- loadstring does not appear to change a variable in a function, is it because x is local
    print(x)
    print(z)
end

doloadstring('0', 'x = 1') -- x is not changed
doloadstring('0', 'z = 1') -- z is created tho

这是输出:

this works as I expect
1
this does not
0
0
nil
0
0
1

是的,结果是因为函数获取的环境中不存在那个变量x(两者没有以任何方式连接)。有像 debug.upvaluejoin, debug.setupvalue, and debug.setlocal 这样的函数,但是其中 none 会将一个局部变量“连接”到一个函数 upvalue 上,使它们成为一回事。

您可以执行以下操作:(1) 创建一个新环境,(2) 用局部变量和上值(的值)填充它,(3) 使用该环境调用函数(将环境传递给 load 用于 Lua 5.2+ 或在 Lua 5.1 中使用 setfenv),然后 (4) 从该环境中获取任何更改并将它们分配回本地 variables/upvalues(您可以使用代理 table 来简化更改的检测)。

您可以检查 restore_vars and capture_vars Mobdebug 中执行类似操作的函数。它解决了大多数情况下的问题(当您没有任何关于“加载”函数中可能使用的变量的信息时),因此如果您有一些相关信息,您绝对可以简化逻辑并通过符合您需要的特定环境(您不需要捕获 all 上值和局部变量)。