[英]Lua metatables and metamethod - How to call a different member function
我有以下课程
local PROGRESS = {}
PROGRESS.__index = function(self,key)
if key~="__group" and self.__group[key] then
return self.__group[key]
else
return rawget(self,key)
end
end
这是什么,当您访问table[key]
它将在table.__group
(这是另一个类的对象)中执行查找,并返回table.__group[key]
(如果它不是nil)。
现在,我尝试对成员函数执行相同的操作。 即如果我调用table:key()
必须在table.__group
执行查找,并且如果存在该函数,则应该调用table.__group:key()
。
我该如何完成?
我试图做到这一点。
local PROGRESS = {}
PROGRESS.__index = function(self,key)
if key~="__group" and self.__group[key] then
local val = self.__group[key]
if type(val) == "function" then
self.__group:val()
return function() end
end
return self.__group[key]
else
return rawget(self,key)
end
end
但是这里有两件事是错误的。
table[key].function
而没有调用它,则该函数将被调用 而且我有一种使事情变得复杂的感觉,并且解决方案更简单。
任何帮助表示赞赏。
UPDATE
@Mud原始代码的问题在于,作为“自身”传递给成员函数的对象是新类的对象。 不是老套的。
考虑这段代码
GROUP_CLASS = {}
GROUP_CLASS.__index = GROUP_CLASS
function GROUP_CLASS:showSum (a,b) print(self);print(a + b) end
group_object = setmetatable({},GROUP_CLASS)
group_object:showSum(1,2)
local PROGRESS_CLASS = {}
PROGRESS_CLASS.__index = function(self,key,value)
if key~="__group" and self.__group[key] then
return self.__group[key]
else
return rawget(self,key)
end
end
progress_object = setmetatable( {__group = group_object} , PROGRESS_CLASS)
progress_object:showSum(3,3)
--progress_object is passed as first argument to showSum. But i need group_object to be passed
在上面的代码中,当调用progress_object:showSum(3,3)
,是否可以将group_object(或称为progress_object .__ group)作为自身而不是progress_object传递。
希望有道理。
对更新后的帖子的回复:
将progress_object作为第一个参数传递给showSum。 但是我需要通过group_object
如果要忽略对象的状态,则调用一个方法,并替换其他对象的状态,为什么它甚至是该对象上的方法? 这就像重写加法运算符进行乘法一样,这是造成混淆的秘诀。
换句话说,您想要这样:
progress_object:method("foo")
通过怪异的内部机制解决:
group_object:method("foo")
为什么不跳过一步而只打后面的电话呢?
如果必须的话 ,可以通过返回用__group
代替self
的方法的代理来实现
local PROGRESS_CLASS = {}
PROGRESS_CLASS.__index = function(self,key)
local groupval = self.__group[key]
if key == '__group' or not groupval then
return rawget(self,key)
elseif type(groupval) ~= 'function' then
return groupval
else
return function(...)
if self == ... then -- method call
-- replace self argument with __group
return groupval(self.__group,select(2,...))
else
return groupval(...)
end
end
end
end
对原始帖子的回复:
我如何尝试对成员函数执行相同的操作。 即如果我调用
table:key()
必须在table.__group
执行查找,并且如果存在该函数,则应该调用table.__group:key()
。我该如何完成?
没做什么。 您的原始代码可以处理此问题。
Lua不知道什么是“成员函数”。 成员是成员(即表中的元素),并且该成员的值是否为函数无关。
记得:
obj:method(a,b,c)
完全等同于obj.method(obj,a,b,c)
obj.method
与obj["method"]
完全等效。 obj["method"]
解析为obj.__group["method"]
这样就完成了。
例如,假设我们有:
group = {}
function group:showSum (a,b) print(a + b) end
function group:showProduct(a,b) print(a * b) end
使用您的第一个代码,我们可以编写:
foo = setmetatable({__group = group}, PROGRESS)
foo:showSum(3,3) -- 6
foo:showProduct(3,3) -- 9
而已。
现在,只要我们在这里,就让我们看看第二个函数在做什么:
local val = self.__group[key]
if type(val) == "function" then
self.__group:val()
return function() end
end
首先,您从__group
获取函数值。 至此,您已经完成。 只需返回该值,调用者便会调用该值(即(...)
)。 而是,您调用__group["val"]
可能与__group[key]
完全不同(除非key ==“ val”),然后再向调用方传递一个不执行任何操作的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.