假设我使用:运算符声明一个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调用它?
答案 0 :(得分:7)
你没有。至少,Lua不会告诉你。
就Lua而言, function ClassName:myFunc( stuff )
只是语法糖。它与此没有什么不同: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不会完全拯救你自己。
答案 1 :(得分: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