gpt4 book ai didi

oop - Lua 元表和元方法 - 如何调用不同的成员函数

转载 作者:行者123 更新时间:2023-12-01 09:09:21 25 4
gpt4 key购买 nike

我有以下类(class)

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] ,如果它不为零。

现在我正在尝试对成员函数执行相同的操作。即如果我调用 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

但是这里有两处错误。

  1. 我无法检索原始函数的参数
  2. 事件如果我只是访问 table[key].function 而没有调用它,该函数将被调用

而且我有一种感觉,我正在努力使事情复杂化,而解决方案要简单得多。

感谢任何帮助。

更新

@泥巴原始代码的问题在于,作为“self”传递给成员函数的对象是新类的对象。不属于旧类(Class)。

考虑这段代码

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)作为 self 而不是 progress_object 传递。

希望这是有道理的。

最佳答案

对更新帖子的回应:

progress_object is passed as first argument to showSum. But i need group_object to be passed

如果您要忽略调用方法的对象的状态,并替换其他某个对象的状态,为什么它甚至是该对象的方法?这就像覆盖加法运算符来执行乘法,这是一种混淆的方法。

换句话说,你想要这个:

progress_object:method("foo")

通过奇怪的内部机制解决这个问题:

group_object:method("foo")

为什么不跳过一个步骤直接调用后者呢?

如果您必须,您可以通过返回将 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

对原帖的回复:

How I am trying to do the same for member functions. i.e If I call table:key() a lookup must be performed in table.__group and if the function is present, then table.__group:key() should be called.

How do I accomplish this?

什么都不做。您的原始代码会处理此问题。

Lua 不知道什么是“成员函数”。成员就是成员(即表中的元素),与该成员的是否为函数无关。

记住:

  1. obj:method(a,b,c) 完全等同于 obj.method(obj,a,b,c)
  2. obj.method 完全等同于 obj["method"]
  3. 您的代码已经将 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"),然后您传递调用一个什么都不做的函数。

关于oop - Lua 元表和元方法 - 如何调用不同的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11232680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com