Lua类中__call元方法无法生效的原因是什么?
Lua中__call元方法无法触发的问题解决
你的问题出在**__call元方法的位置放错了**:你把它定义在了实例对象的元表里,而不是test这个类表的元表中。当尝试调用test()时,Lua会去查找test表的元表中的__call方法,但test本身没有设置元表,自然找不到该方法,因此报错。
你用setmetatable(self, self)是给每个实例设置元表为自身,这只会影响实例的行为(比如实例的__tostring、属性查找),和类表test能否被调用没有关系。
修复方案
直接给test类表设置元表,并把__call元方法放在这个元表里,修改后的代码如下:
test = {} -- 给test类表设置元表,添加__call方法 setmetatable(test, { __call = function(cls, ...) print("Constructor called!") return cls:new(...) end }) function test:new() local self = {} setmetatable(self, self) self.__index = self -- 私有属性 local str = "hello world" -- 实例的元方法和公开方法 self.__tostring = function() return "__tostring: "..str end self.tostring = function() return "self:tostring(): "..str end return self end local t = test:new() print(t) -- __tostring正常工作 print(tostring(t)) -- __tostring正常工作 print(t:tostring()) -- 公开方法正常调用 t = test() -- 现在可以触发__call,调用构造函数
修改后的运行输出:
__tostring: hello world __tostring: hello world self:tostring(): hello world Constructor called! __tostring: hello world
这个修改完全保留了你setmetatable(self, self)的写法(确实能降低实例创建的开销),同时解决了类表无法被调用的问题。
内容的提问来源于stack exchange,提问作者Bernard Langham
相关产品推荐
相关产品推荐

