2012-06-11 67 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