Sat*_*hJM 2 oop lua class object metatable
我有以下课程
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
Run Code Online (Sandbox Code Playgroud)
这样做是当你访问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
Run Code Online (Sandbox Code Playgroud)
但这里有两件事是错的.
table[key].function没有调用它,该函数将被调用我感觉我正在努力使事情复杂化,解决方案更简单.
任何帮助表示赞赏.
UPDATE
@Mud原始代码的问题是作为'self'传递给成员函数的对象是新类的对象.不是老班.
考虑这段代码
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
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,progress_object:showSum(3,3)调用When时 ,是否可以将group_object(或者换句话说progress_object .__ group)作为self而不是progress_object传递.
希望有道理.
对更新后的回复:
progress_object作为showSum的第一个参数传递.但我需要传递group_object
如果你要忽略一个方法被调用的对象的状态,并替换一些其他对象的状态,为什么它甚至是该对象的方法?这就像重写加法运算符来进行乘法运算一样,这是一种混淆的方法.
换句话说,你想要这个:
progress_object:method("foo")
Run Code Online (Sandbox Code Playgroud)
通过奇怪的内部机器解决这个问题:
group_object:method("foo")
Run Code Online (Sandbox Code Playgroud)
为什么不跳过一步而只是拨打后一个电话呢?
如果你一定要,你可以通过它取代了方法返回的代理实现这一目标self用__group
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
Run Code Online (Sandbox Code Playgroud)
回复原帖:
我如何尝试为成员函数做同样的事情.即如果我调用
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
Run Code Online (Sandbox Code Playgroud)
使用您的第一个代码,我们可以写:
foo = setmetatable({__group = group}, PROGRESS)
foo:showSum(3,3) -- 6
foo:showProduct(3,3) -- 9
Run Code Online (Sandbox Code Playgroud)
而已.
现在,只要我们在这里,让我们来看看你的第二个功能在做什么:
local val = self.__group[key]
if type(val) == "function" then
self.__group:val()
return function() end
end
Run Code Online (Sandbox Code Playgroud)
首先从中获取函数值__group.此时你已经完成了.只需返回该值,调用者就会调用该值(即(...)).相反,你调用__group["val"]哪个可能是一个完全不同的函数__group[key](除非键=="val"),然后你传递给调用者一个什么都不做的函数.