2016-01-22 46 views
5

我對獲取函數的任何返回格式感興趣。例如Lua - 我如何獲得任何回報?

function foo() 
    return 1 
end 

local result = foo() -- foo is numeric 1 

function foo() 
    return {1,2,3} 
end 
local result1, result2, result3 = foo() 
local result = foo() -- this is bad as result is `1` but `2` and `3` are lost 

function foo() 
    return 1, 2, 3 
end 
local result = foo() -- foo is a table with all the numbers, that's ok 

我建立一個分析器,這將覆蓋功能與代理功能,但我需要知道返回的數據,然後檢查它的type()和訪問accordingly`但是從代碼可以看出,我無法使用一種方法訪問所有3種情況。有沒有 ?

+0

@NicolBolas,因爲我已經給了富的'三個例子()'函數應該清楚,我想抓住這三種情況下foo'的'。請不要在這裏需要切線。 –

+0

@NicolBolas謝謝你的幫助:)我已經更新了我的問題,我希望現在更清楚 –

+0

所以你是這個函數的實際調用者。你打算檢查這些結果,然後返回它們,就好像你是'foo'? –

回答

8

如果返回的最大數量是已知的,使用類似

v1,v2,v3 = foo() 

,但你不能告訴foo是否返回兩個值,三,隨着最後一個是零。

堅固的解決辦法是收集所有返回表:

v = table.pack(foo()) 

然後v.n包含返回的值,包括所有尼爾斯的數量。

+4

請注意,table.pack需要Lua 5.2+ –

+4

自4年前發佈Lua 5.2以來,除非您使用僅支持Lua 5.1的LuaJIT,否則應該可以。 – lhf

+0

這就是我想要的!謝謝! –

4

這是一個適用於任何Lua版本5.1+的版本。

local function WrapAndInspect(Inspector, FunctionToCall) 
    local function Inspect(...) 
     Inspector(...) 
     return ... 
    end 
    local function Wrapper(...) 
     return Inspect(FunctionToCall(...)) 
    end 
    return Wrapper 
end 

WrapAndInspect做什麼是生成將調用指定的功能,然後通過它的返回值,爲您提供第二個函數的函數。該功能可以做任何你認爲對他們有必要的處理。但是框架將確保原始函數的返回值按原樣傳遞。

這裏有一個變化,做類似的東西,但不是包裹FunctionToCall,它返回一個函數,需要一個被調用的函數(連同其參數):

local function CallAndInspect(Inspector) 
    local function Inspect(...) 
     Inspector(...) 
     return ... 
    end 
    local function Caller(FunctionToCall, ...) 
     return Inspect(FunctionToCall(...)) 
    end 
    return Caller 
end 

您可以使用此一個關於你想要檢查的特定功能。

3

以下是無法訪問table.pack的解決方法。 對我來說,它似乎很簡單,它應該適用於lua 5.1及更高版本 - 甚至可能更早的lua版本。

table_pack應該像table.pack

function table_pack(...) 
    return {n=select("#", ...), ...} 
end 
function foo() 
    return 1, 2, 3 
end 

local v = table_pack(foo()) 
print(v.n) 
+1

'...'最後必須擴展爲所有參數,所以'{n = select(「#」,...),...}'效果更好! – siffiejoe

+0

@siffiejoe我想知道是否有任何真正的區別。我在lua 5.3上測試了這個代碼。 是否有任何情況下,它實際上「更好地發揮作用」 - 就像你說的那樣? – Rochet2

+2

*有*真正的區別:您的代碼僅適用於一個參數。你可以通過添加'for i = 1,v.n do print(i,v [i])end'來檢查上面的示例代碼。從Lua手冊[quote](http://www.lua.org/manual/5.3/manual.html#3.4.9):如果列表中的最後一個字段的形式爲exp,並且表達式是一個函數調用或可變參數表達式,則此表達式返回的所有值都會連續輸入列表(請參閱第3.4.10節)。 '...'不是表格構造函數中的最後一個表達式,所以它被調整爲一個值。 – siffiejoe