2012-04-04 127 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 
相關問題