7

有没有办法

  • 两个 Lua 模块(我们称它们为Aand B
  • 每个模块都使用另一个模块的功能,因此它们必须require相互
  • 第三个模块(我们称之为C)可以使用A但不能B使用

C.lua

local A = require 'A'

-- ...

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

相关Lua - 我如何使用另一个库?(注意:此解决方案不处理循环依赖。)

4

3 回答 3

6

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

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-23T20:48:37.793 回答
3

在任何语言中执行此操作的标准方法是引入中介。然后模块可以发布和订阅中介。 http://en.wikipedia.org/wiki/Mediator_pattern

我的语言中的一个示例是 mvccontrib 总线、IEventAggregator 和 MVVM Lite Messenger 类。他们都做同样的事情。

于 2011-12-07T11:11:56.920 回答
3

Owen Shepherd 在lua-l 邮件列表中建议的另一种方法:

如果我们在每个模块的顶部设置,那么后面的任何其他模块 d 都可以引用当前(可能不完整)的模块。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' 的初始化依赖于then 如果首先加载A.baz它将失败,因为将看到in尚未定义的不完整版本。ABAbaz

于 2012-12-20T22:55:47.790 回答