Lua - 我怎么才能获取任何返回值?

我对获取函数的任何返回格式感兴趣。例如:

function foo()
  return 1
end

local result = foo() -- foo是数字1

function foo()
  return {1,2,3}
end
local result1, result2, result3 = foo()
local result = foo() -- 这很糟糕,因为result是 `1` 但 `2` 和 `3` 被丢失了

function foo()
  return 1, 2, 3
end
local result = foo() -- foo是带有所有数字的表,这没问题

我正在构建一个分析器,它将使用代理函数重写函数,但我需要知道返回的数据,以便根据 type() 进行访问,但从代码中可以看出,我无法使用一种方法访问所有三种情况。是否有解决方案?

点赞
用户107090
用户107090

如果已知返回值的最大数量,可以使用以下方式:

v1,v2,v3 = foo()

但你无法判断 foo 函数返回的是两个值还是三个值,其中最后一个值是 nil

更为健壮的解决方案是将所有的返回值收集到一个表中:

v = table.pack(foo())

接下来,v.n 中包含了所有返回值的数量,包括所有的 nil 值。

2016-01-22 15:14:56
用户734069
用户734069

以下是适用于任何 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

您可以在要检查的任何特定函数上使用此函数。

2016-01-22 15:23:54
用户3586583
用户3586583

以下为没有访问table.pack的解决办法。 在我看来,它似乎很简单,应该适用于lua5.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)
2016-01-22 21:39:10