在Lua 5.2中,建议采用递归引用的方式使2个或2个以上的模块相互引用。

有没有办法实现:

  • 两个 Lua 模块(假设为 AB
  • 每个模块都要使用另一个模块中的函数,因此它们必须互相 require
  • 第三个模块(假设为 C)可以使用 A,但不能使用 B。例如:

C.lua:

local A = require 'A'

-- ...

A.foo()
  • 可能会有另一个模块 D 需要 B,但不需要 A,或者 E 需要同时需要 AB
  • 既不应该将 AB 或它们的成员添加到全局命名空间中。
  • 避免使用 modulesetfenv 函数(在 Lua 5.2 中已弃用)

相关: Lua - how do I use one lib from another?(注意:该解决方案不能处理循环依赖。)

原文链接 https://stackoverflow.com/questions/8248698

点赞
stackoverflow用户12048
stackoverflow用户12048

我找到了一个非常简单的方法:

A.lua:

local A = {}
local B

function A.foo()
    B = B or require 'B'
    return B.bar()
end

function A.baz()
    return 42
end

return A

B.lua:

local B = {}
local A

function B.bar()
    A = A or require 'A'
    return A.baz()
end

return B
2011-11-23 20:48:37
stackoverflow用户331668
stackoverflow用户331668

在任何语言中,标准的做法是引入中介者。然后模块可以发布和订阅中介者。http://en.wikipedia.org/wiki/Mediator_pattern

在我的语言中,例如 mvccontrib 总线、IEventAggregator和 MVVM Lite Messenger 类,它们都做着同样的事情。

2011-12-07 11:11:56
stackoverflow用户12048
stackoverflow用户12048

另一种方法,由 Owen Shepherd 在 lua-l 邮件列表上建议:

如果我们在每个模块的顶部设置 package.loaded[current-module-name],那么稍后被 require 的任何其他模块都可以引用当前(可能是不完整的)模块。

A.lua:

local A = {}
package.loaded[...] = A

local B = require 'B'

function A.foo()
    return B.bar()
end

function A.baz()
    return 42
end

return A

B.lua:

local B = {}
package.loaded[...] = B

local A = require 'A'

function B.bar()
    return A.baz()
end

return B

这种方法并非在任何情况下都适用。例如,如果 B 的初始化取决于 A.baz,则如果先加载 A,它将失败,因为 B 将看到 A 的不完整版本,其中 baz 尚未定义。

2012-12-20 22:55:47