2012-12-20 114 views
8

問題

如何避免以下錯誤從Lua 5.1試圖做循環需要?Lua:如何避免循環需要

$ lua main.lua 
lua: ./bar.lua:1: loop or previous error loading module 'foo' 
stack traceback: 
    [C]: in function 'require' 
    ./bar.lua:1: in main chunk 
    [C]: in function 'require' 
    ./foo.lua:1: in main chunk 
    [C]: in function 'require' 
    main.lua:1: in main chunk 
    [C]: ? 

文件結構

main.lua

require "foo" 
require "bar" 
print (Foo.getName()) 
print (Bar.getName()) 

foo.lua

require 'bar' 
Foo = {} 
Foo.name = 'foo' 

function Foo:getName() 
    return Foo.name .. Bar.name 
end 

bar.lua

require 'foo' 
Bar = {} 
Bar.name = 'bar' 

function Bar:getName() 
    return Bar.name .. Foo.name 
end 

期望輸出

$ lua main.lua 
foobar 
barfoo 
+3

密切相關(但對於Lua5.2,並避免全局變量):http:// stackoverflow。com/questions/8248698/recommended-way-to-have-2-modules-recursively-refer-to-each-other-in-lua-5-2 – finnw

回答

8

main.lua

Foo = Foo or require "foo" 
Bar = Bar or require "bar" 
print (Foo.getName()) 
print (Bar.getName()) 

foo.lua

Foo = {} 
Bar = Bar or require "bar" 
Foo.name = 'foo' 

function Foo:getName() 
    return Foo.name .. Bar.name 
end 

return Foo 

bar.lua

Bar = {} 
Foo = Foo or require "foo" 
Bar.name = 'bar' 

function Bar:getName() 
    return Bar.name .. Foo.name 
end 

return Bar 

說明

因爲你設置的全局變量,你可以檢查,看看是否該文件已經被要求(又名;全球再次嘗試之前已定義)要求:

Bar = Bar or require "bar" 

bar.lua然後將不得不返回酒吧的定義;

Bar = {} 
-- ... 
return Bar 

這不會完全解決問題作爲bar.lua期待Foo被定義。爲了解決這個問題,你可以定義一個虛擬變量具有相同的名稱:

Foo = {} 
Bar = Bar or require "bar" 

這是因爲你被推遲的Foo當函數被調用的使用是唯一可能的。如果您想在bar.lua的範圍內致電Foo.name,則最終會出現相同的循環依賴問題。

10

解決此問題的另一種方法是更改​​代碼的結構並將「相互」功能提取到第三個模塊中,FooBar都需要。

+1

最終,這當然是我採取的方法,它提供了一個更好的依賴關係樹。在這種情況下,我對允許循環依賴的解決方案感到好奇。謝謝! –