2

假设我使用 : 运算符声明了一个 lua 函数,如下所示:

function ClassName:myFunc( stuff )
    --do stuff
end

然后说我将该函数存储在一个表中,如下所示:

someTable = {
    ClassName.myFunc,
    someGlobalFunc,
} 

然后,假设我有另一个函数通过表并尝试调用给定函数。

function ClassName:callStuffInThisTable(table)
    -- I go through the table, which might be someTable above, and call all the functions
end

我的问题是,我如何知道表中的函数是否由 ClassName 拥有,以便我可以使用 self 调用它?

4

2 回答 2

7

你没有。至少,Lua 不会告诉你。

function ClassName:myFunc( stuff )就 Lua 而言,它只是语法糖。这和这个没有什么不同:ClassName.myFunc = function (self, stuff)。功能是等价的。同样对于 : 调用语法,ClassName:myFunc(stuff)在语义上等价于ClassName.myFunc(ClassName, stuff).

决定您的功能是什么以及它们的作用。这需要编码纪律。如果您有一个需要在循环中调用的函数列表,那么它们应该被设计为使用相同的参数调用。

有两种方法可以做到这一点。一种方法是使所有函数成为“类函数”:

someTable = {
    ClassName.myFunc,
    function(self, ...) return someGlobalFunc(...) end,
} 

这样,self参数将被忽略。显然,您可以创建一个特殊的函数表对象,该对象具有将“全局”函数插入到将自动生成包装器的表中的函数:

function insertFuncIntoTable(self, func)
  self[#self + 1] = function(self, ...) func(...) end
end

insertFuncIntoTable(someTable, someGlobalFunc)

注意:这些之间存在差异,假设“someGlobalFunc”实际上是全局表的成员(而不是 a local)。此版本将采用_G["someGlobalFunc"] 当前具有的值,就像您的原始代码一样。但是,第一个版本采用它在调用时的值,这可能与someTable创建时的函数不同。

所以这个版本更安全。

或者,您可以使表中的任何“类函数”显式绑定到对象实例:

someTable = {
    function(self, ...) ClassName.myFunc() end,
    function(self, ...) return someGlobalFunc(...) end,
} 

顺便说一句,一般来说,如果你使用:语法声明一个函数,你应该以这种方式使用该函数,通过instance:myFunc(...). 显然它只是一个 Lua 函数,和其他函数一样,所以你可以做你喜欢的事。但是滥用会使理解发生的事情变得更加困难。

Lua 为您提供了强大的功能。但是你仍然需要在编码时进行判断和纪律。Lua 不会(完全)把你从你自己手中拯救出来。

于 2012-04-04T23:36:23.997 回答
0

判断函数是否为 ClassName“拥有”的一种方法是扫描和检查。

ClassName = {}
function ClassName:fn(self) ... end

t = { function() ... end , ClassName.fn() }

function has_value( klass, value )
  for k,v in pairs(klass) do
    if v==value then return true
  end
  return false

function ClassName:callStuffInThisTable(table)
  for k,v in pairs(table) do
    if has_value(ClassName, v) then
      v(self)
    else
      v()
    end
  end
end

由于表扫描,这具有 O(n^2) 行为。我们可以通过使用 ClassName 中的函数作为新表将其减少到 O(n log(n)) )

function ClassName:callStuffInThisTable(table)
  local t = {}
  for k,v in pairs(ClassName) do
    t[v] = 1
  end

  for k,v in pairs(table) do
    if t[v]==1 then
      v(self)
    else
      v()
    end
  end
end   
于 2012-04-05T01:16:56.530 回答