【问题标题】:Why does .__index only return the function from the subclass instead of the base class为什么 .__index 只返回子类而不是基类的函数
【发布时间】:2019-12-31 13:00:14
【问题描述】:
item = {y = 21}

function item:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

function item:Run()
    print("item running")
end

berry = item:new{x = 52}

function berry:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end
function berry:Run()
    print("berry is running")
    self.__index:Run()
end

berry:new{b = 32}:Run()

当它应该打印“berry is running”然后是“item running”时,输出会无限打印“berry is running”。如果我将self.__index 更改为self.__index.__index 甚至更改为self.__index.__index.__index,输出仍然会无限打印“berry is running”。我该如何纠正这个问题?任何帮助将不胜感激

【问题讨论】:

  • getmetatable(self):Run()替换self.__index:Run()
  • @EgorSkriptunoff "item running" 被打印一次,但 "berry is running" 被打印两次而不是一次。如果我从 berry 创建另一个子类,这仍然有效吗?
  • 我的Run() 对层次结构中的每个级别执行一次。这就是为什么有 3 条消息:来自子类、来自类 berry 和来自类 item

标签: oop lua


【解决方案1】:

您在berry 中覆盖了itemRun 函数,这使其更难访问。此覆盖会导致您的无限循环,因为 self.__indexto self 的引用,它是 berry。现在 Run 在 berry 中定义 __index 将不再在 berryRun 索引时被调用

所以你的berry:Run 函数本质上是

function berry:Run()
    print("berry is running")
    berry:Run()
end

我建议你改变你的berry:Run函数,并在其中专门调用item.Run

function berry:Run()
    print("berry is running")
    item.Run(self) -- specifically call item.Run and pass it self.
end

这将为您提供所需的输出:

浆果正在运行

项目运行


或者,您可以通过在运行之前在 berry 中定义 item:Run 函数来保持它:

berry.ParentRun. = berry.Run -- this will cause __index to run and get item:Run
function berry:Run()         -- This now defines berry.Run. now __index will no longer run for berry.Run
    print("berry is running")
    self:ParentRun()         
end

注意事项:

你看到的原因

浆果正在运行

浆果正在运行

项目运行

来自 cmets 的建议是因为运行的顺序是

object:Run() -- this calls berry passing the self of object

打印我们的第一个 berry 正在运行

现在我们获取该对象的元表,即 berry 并将其称为 run

berry:Run()

打印我们的第二个浆果正在运行

最后我们得到了 berry 的元表 item 并称之为 run

item:Run()

打印项目运行

【讨论】:

    猜你喜欢
    • 2021-01-06
    • 2017-06-07
    • 2011-09-16
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多