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()


输出应无限打印“浆果正在运行”,而应先打印“浆果正在运行”,再打印“项目正在运行”。如果我将self.__index更改为self.__index.__index甚至更改为self.__index.__index.__index,输出仍将无限打印“浆果正在运行”。我该如何纠正?任何帮助,将不胜感激

最佳答案

您已在Run中覆盖了itemberry功能,这使得更难以访问。此覆盖会导致无限循环,因为self.__index是对self的引用,而berryRun。既然在浆果__index中定义了berry,当用Run索引berry:Run时将不再调用
因此,您的berry:Run函数本质上是

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


我建议您更改item.Run函数,并在其中专门调用item:Run
function berry:Run()
    print("berry is running")
    item.Run(self) -- specifically call item.Run and pass it self.
end

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

浆果正在运行
项目运行


另外,您可以通过在运行之前在berry中定义函数来持久化函数:
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


奖金说明:
你看到的原因

浆果正在运行
浆果正在运行
项目运行

从评论中的建议是因为运行顺序将是
object:Run() -- this calls berry passing the self of object

打印我们的第一个浆果正在运行
现在我们获取该对象(浆果)的元表,并称之为运行
berry:Run()

打印我们的第二个浆果正在运行
最后,我们得到berry的metatable,它是item,并称之为运行
item:Run()

打印项目正在运行

10-05 18:59