我的代码:
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
但是,如果我将表A
和B
设置为本地,如下所示:
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
文件的所有函数和变量都放在唯一命名的表中,以避免每个文件之间的名称冲突?
答案 0 :(得分:5)
局部变量是定义它们的脚本的私有变量。这就是重点。
如果要从脚本中导出内容,请返回该内容。定义库的脚本通常返回一个表。这比污染全球环境要礼貌得多。
答案 1 :(得分: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);
}
这也应该回答您的其他问题:不,使用如上所述的模块。