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
中覆盖了item
的berry
功能,这使得更难以访问。此覆盖会导致无限循环,因为self.__index
是对self
的引用,而berry
是Run
。既然在浆果__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()
打印项目正在运行