Lua中函数内使用loadstring无法修改局部变量是什么原因?
Lua loadstring无法修改函数入参的成因
你的猜测完全正确,具体原因可以拆解为以下几点:
loadstring加载代码字符串生成的函数,默认使用全局环境_G作为执行环境,只能访问、修改全局环境下的变量,没有权限访问调用位置的外层局部变量。- 你自定义的
doloadstring函数的入参x是函数的局部变量,存储在Lua运行时的栈帧中,不属于全局环境_G的键值对。你在loadstring中执行x = 1时,本质是给全局变量_G.x赋值,和函数内的局部变量x是完全独立的两个值,所以函数内打印的局部x不会发生变化。 - 你执行
loadstring('z = 1')()时可以成功创建全局变量,是因为赋值操作直接写入了全局环境_G,所以后续访问z时可以读到_G.z的存储值。
如果你需要让loadstring能够修改函数的局部入参,可以通过自定义执行环境的方式实现,示例代码如下:
function doloadstring(x, s) -- 自定义执行环境,先把局部x放入环境 local custom_env = {x = x} -- 让自定义环境 fallback 到全局环境,保证全局变量可以正常访问 setmetatable(custom_env, {__index = _G, __newindex = _G}) local func = loadstring(s) -- 给生成的函数绑定自定义环境 setfenv(func, custom_env) func() -- 把环境中修改后的x同步回局部变量 x = custom_env.x print(x) end doloadstring(0, 'x = 1') -- 此时输出为1
注:上述代码适用于Lua 5.1版本,5.2及以上版本可以直接用load函数的env参数指定执行环境,无需调用setfenv。
内容的提问来源于stack exchange,提问作者likethevegetable
相关产品推荐
相关产品推荐

