2012-04-04 125 views
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调用它?

+1

出于好奇,为什么你想要/需要调用所有的函数在给定的表) ,你不能也要求所有这些函数都是*所有*是类方法或*所有*是裸函数? – Amber 2012-04-04 23:32:14

回答

7

你不知道。至少,Lua不会告诉你。

function ClassName:myFunc(stuff)就Lua而言,它只是句法糖。这与此没有什么不同:ClassName.myFunc = function (self, stuff)。这些功能是等同的。 同样,对于:call语法,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”是实际上是全球表格的成员(而不是local)。此版本将采用_G["someGlobalFunc"]目前的值,就像您的原始代码一样。但是,第一个版本的值为,它被称为,它可能与创建时的someTable时间不同。

所以这个版本更安全。

或者,你可以让这个表中的任何“类函数”明确绑定到一个对象实例:

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

顺便说一句,在一般情况下,如果使用:语法声明函数,你'使用这样的功能,通过instance:myFunc(...)。显然它只是一个Lua函数,所以你可以做你喜欢的。但滥用可以让人更难理解正在发生的事情。

Lua为您提供了很多动力。但是在编码时你仍然需要做出判断和纪律。 Lua不会完全保存你自己。

+0

感谢您的洞察力。我没有做出的飞跃是因为函数是匿名的,他们的名字没有任何意义。 最后我想要做的是使一个脚本,通过功能和参数,等待在必要时进行迭代,所以我这样做: 脚本= {{ FUNC,{PARAMS}}} 理想情况下,虽然我会有用户功能和预先实现的功能。我可以轻松传递一个自己的对象,我只是想变得聪明。 – 2012-04-05 01:11:49

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)行为。我们可以将此减少到O(N日志(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 
相关问题