【问题标题】:How to access local table variable from other script如何从其他脚本访问本地表变量
【发布时间】:2018-07-17 10:20:40
【问题描述】:

我的代码:

lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
//Script A
luaL_dostring(L, "A = {} A.num = 3");
//Script B
luaL_dostring(L, "B = {} function B.update() return A.num * 2 end");
//Script C
luaL_dostring(L, "print(B.update())"); 
lua_close(L);

结果:6

但是,如果我将表 AB 设为本地,如下所示:

lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
//Script A
luaL_dostring(L, "local A = {} A.num = 3");
//Script B
luaL_dostring(L, "local B = {} function B.update() return A.num * 2 end");
//Script C
luaL_dostring(L, "print(B.update())"); 
lua_close(L);

它不输出任何东西。

如何使第二个代码工作,两者之间更推荐的设计是什么?

附加问题:将所有函数和变量放在每个 .lua 文件的唯一命名表中是 Lua 中避免每个文件之间名称冲突的常用技术吗?

【问题讨论】:

  • 局部变量不能从其词法范围之外访问。它们的词法范围在定义它们的块内。每个dostring 引入单独的块。
  • 始终检查错误!第二个示例中的luaL_dostring(L, "print(B.update())"); 将失败,并显示类似failed to index nil global "B"

标签: lua


【解决方案1】:

局部变量对于定义它们的脚本来说是私有的。这就是重点。

如果您想从脚本中导出某些内容,请将其返回。定义库的脚本通常会返回一个表。这比污染全球环境礼貌多了。

【讨论】:

  • 感谢您的回答。您能否通过修改我的第二个示例来显示一个示例,以便它可以打印6
【解决方案2】:

正如 Luiz Henrique 已经提到的,local 变量不能在其范围之外访问,并且使用硬编码名称污染全局环境是不礼貌的。

相反,您可以利用我已经在this answer of mine 中提出的技巧来解决您的另一个问题。使用luaL_loadstring 而不是luaL_dostring 将脚本加载到函数中,并将此函数注册为package.preload 中的字段。然后,在您的块中,您可以轻松地将预加载的模块require 放入局部变量中。

#include <lua.hpp>

int main() {
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    lua_settop(L, 0);

    lua_getglobal(L, "package");
    lua_getfield(L, -1, "preload");

    // Script A
    luaL_loadstring(L, "return { num = 3 }");
    lua_setfield(L, -2, "A");

    // Script B
    luaL_loadstring(L, "local A = require('A')\n"
                       "return { update = function() return A.num * 2 end }");
    lua_setfield(L, -2, "B");

    // Script C
    luaL_dostring(L, "local B = require('B')\n"
                     "print(B.update())");

    lua_close(L);
}

这也应该回答您的附加问题:不,使用如上所述的模块。

【讨论】:

  • 非常感谢。这太棒了!
猜你喜欢
  • 2015-07-30
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 2021-04-15
  • 2018-08-10
  • 2017-06-25
  • 1970-01-01
相关资源
最近更新 更多