繁体   English   中英

Lua元表和元方法-如何调用其他成员函数

[英]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 

但是这里有两件事是错误的。

  1. 我无法检索原始函数的参数
  2. 事件,如果我只是访问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不知道什么是“成员函数”。 成员是成员(即表中的元素),并且该成员的是否为函数无关。

记得:

  1. obj:method(a,b,c)完全等同于obj.method(obj,a,b,c)
  2. obj.methodobj["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”),然后再向调用方传递一个不执行任何操作的函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM