2012-06-11 63 views
0

我在文件中有一些lua代码。我想创建这个代码的多个闭包实例,每个实例都有一个不同的_ENV upvalue。我可以使用luaL_loadfile加载文件,并使用不同的表设置第一个upvalue N次,以创建N个实例。但是这不会加载和编译N次?Lua创建多个闭包实例

的LUA相当于什么,我想要做的是下面的,只是没有使用loadFile

func_list = {} 

for i = 1, 10 do 
    local new_env = {hello=i, print=print} 
    func_list[i] = loadfile("Code.lua", "t", new_env) 
end 

for i = 1, 10 do 
    func_list[i]() 
end 

------ Code.lua ------ 
print(hello*hello) 

有没有更好的方式来做到这一点?

回答

1

每当装入在Lua字符串/文件,你得到的回报是什么是一个函数调用实际运行文件,改变它的包膜。 load为您所做的只是一些额外的处理来设置_ENV

但是,没有什么能阻止你自己设置_ENV。你可以使用像这样做:

-- Code.lua -- 
_ENV = ... 
print(hello * hello) 

然后,你可以加载/编译文件只需一次,并使用多个实例为这样:

local code = loadfile("Code.lua") 

env_list = {} 
for i = 1, 10 do 
    local new_env = {hello=i, print=print} 
    code(new_env) 
    env_list[i] = new_env 
end 

如果你不希望用户在每个文件中都写入_ENV = ...,您可以将该文件加载到字符串中,自行添加该行并使用load来编译源文件。但是这对编译的文件不起作用。

+0

是不是指for循环中的'code(new_env); func_list [i] = new_env'。 – z33m

+0

此外,不要将'_ENV = ...'附加到代码中。 DeadMG的建议也应该正确吗?即。在执行块之前将第一个upvalue设置为new_env – z33m

+0

感谢您的评论,我解决了这个问题。关于第二个问题 - 你可以使用[这个实现'setfenv' for Lua 5.2](http://lua-users.org/lists/lua-l/2010-06/msg00313.html)来获得你想要的。只要注意,现在你只有一个闭包,它改变了它的环境,而不是多个闭包。 –

1

使用IO库将文件加载到一个字符串中,然后在其上调用loadstring

或者,只得到一个大块,然后之前执行它

+0

如果我使用'loadstring',它会每次编译代码,对吧? – z33m

+0

@ z33m:是的,但至少您不必执行I/O。编译后无法复制Lua块。 – Puppy