2012-12-20 82 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

最终,这当然是我采取的方法,它提供了一个更好的依赖关系树。在这种情况下,我对允许循环依赖的解决方案感到好奇。谢谢! –