eli*_*00d 6 lua dependencies require
我最近遇到了一个问题,我看到错误“太多 C 级别(限制为 200)”。
它到底意味着什么?我该如何防止这种情况发生?
我认为这与循环需求有关,但它指向我的代码中创建类的新实例的一行,如下所示:
Class:new()
Run Code Online (Sandbox Code Playgroud)
至于我的模块,我确实有一些循环需求,但我尝试通过将外部类移动到同一个模块中来修复它们,如下所示:
Class.SubClass = Class:new()
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
更新:
这是我遇到的一个例子:
lua类
local Class = {}
function Class:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
return Class
Run Code Online (Sandbox Code Playgroud)
类/Entity.lua
local Class = require('Class')
local Player = require('classes/Player')
local Entity = Class:new()
function Entity:getPlayer()
return Player:new()
end
return Entity
Run Code Online (Sandbox Code Playgroud)
类/Player.lua
local Class = require('Class')
local Entity = require('classes/Entity')
local Player = Class:new()
function Player:getEntities()
local entities = {}
for i = 1, 100 do
entities[i] = Entity:new()
end
return entities
end
return Player
Run Code Online (Sandbox Code Playgroud)
我意识到这是一个循环依赖,但我找到的唯一解决方案是:Lua:如何避免循环需要,它使用全局变量。当地人有办法避免这种情况吗?
首先,我会仔细研究为什么Entity:getPlayer需要存在以及为什么它会创造一个新的玩家。(即使这是示例代码,为什么实体依赖于玩家而不是相反?)
让我们看一下在没有全局变量的情况下解决这个问题的几种方法。
TL;DR:遵循“模块拆分”解决方案。
这是@Egor 的解决方案。它将模块导入从文件加载时间移至运行时。这稍微隐藏了您的依赖项,但这是解决 require 循环的最小更改。
类/Entity.lua
local Class = require('Class')
local Player
local Entity = Class:new()
function Entity:getPlayer()
Player = Player or require('classes/Player')
return Player:new()
end
return Entity
Run Code Online (Sandbox Code Playgroud)
将玩家传递给需要它的实体。
类/Entity.lua
local Class = require('Class')
local Player = require('classes/Player')
local Entity = Class:new()
function Entity:init(player_class)
self.player_class = player_class
end
function Entity:getPlayer()
return self.player_class:new()
end
return Entity
Run Code Online (Sandbox Code Playgroud)
类/Player.lua
local Class = require('Class')
local Entity = require('classes/Entity')
local Player = Class:new()
function Player:getEntities()
local entities = {}
for i = 1, 100 do
-- Or instead, we might pass the relevant player instance (self).
entities[i] = Entity:new(Player)
end
return entities
end
return Player
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个解决方案,因为它要求您始终需要具有相同路径的entity.lua。如果有时使用require('classes/Entity'),有时
使用,Lua 模块可能有不同的定义require('classes.Entity')。对于部分类来说,这可能是一个很好的模式,但这看起来不像你正在做的事情。无论如何,列出是为了完整性。
如果您有一个全局实体或拥有它的另一个模块,您可以在那里进行注入以解决路径风险。
类/Player.lua
local Class = require('Class')
local Entity = require('classes/Entity')
local Player = Class:new()
...
-- Adding functionality to an imported module.
function Entity:getPlayer()
return Player:new()
end
return Player
Run Code Online (Sandbox Code Playgroud)
这是最干净的解决方案之一。当您有两个相互依赖的东西时,使它们独立并将依赖关系移到更高的模块中。然而,它也是距离当前代码最远的。您最终可能会像全局变量一样使用 Population 实例,但并不要求它是全局变量。
类/Population.lua
local Class = require('Class')
local Entity = require('classes/Entity')
local Player = require('classes/Player')
local Population = Class:new()
function Population:getPlayer()
return Player:new()
end
function Population:getEntities()
local entities = {}
for i = 1, 100 do
entities[i] = Entity:new()
end
return entities
end
return Population
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3223 次 |
| 最近记录: |