2016-01-22 43 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