Lua: 函数内的 loadstring 看起来无法工作?

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

我猜测 x 是一个本地变量,而 loadstring 只有全局作用域?`

print('这符合我的预期')
x = 0
loadstring('x = 1')()
print(x)

print('这个不行')
function doloadstring(x, s)
    print(x)
    loadstring(s)() -- loadstring 似乎无法更改函数中的变量,这是因为 x 是局部变量吗
    print(x)
    print(z)
end

doloadstring('0', 'x = 1') -- x 没有改变
doloadstring('0', 'z = 1') -- z 虽然被创建了

这是输出结果:

这符合我的预期
1
这个不行
0
0
nil
0
0
1

原文链接 https://stackoverflow.com/questions/69489814

点赞
stackoverflow用户1442917
stackoverflow用户1442917

是的,结果是由于变量 x 在函数所在的环境中不存在(两者没有任何关联)。虽然有一些函数类似于 debug.upvaluejoindebug.setupvaluedebug.setlocal,但它们都无法将本地变量和函数的 upvalue "连接",使它们成为同一个变量。

你可以执行以下步骤:(1)创建一个新的环境,(2)用本地变量和 upvalue 的值填充它,(3)使用该环境调用函数(将环境传递给 Lua 5.2+ 的 load 或在 Lua 5.1 中使用 setfenv),然后(4)将该环境中的任何更改赋回本地变量/ upvalue(你可以使用代理表来简化检测更改的过程)。

你可以检查 Mobdebug 中的 restore_vars 和 capture_vars 函数,它们做了类似的事情。它在最一般的情况下解决了该问题(当你没有关于可能在你的“加载”函数中使用的变量的任何信息时),因此,如果你有一些关于它的信息,你绝对可以简化逻辑并传递一个特定的环境,以匹配你需要的内容(你不需要捕获 所有 的 upvalue 和本地变量)。

2021-10-08 05:09:57