结合两个可变函数结果

时间:2014-01-09 22:51:51

标签: function lua variadic-functions variadic

假设我有两个可变函数,如下所示:

function a(num)
  if num == 1 then
    return 1
  else
    return 1, 2
  end
end    

function b(num)
  if num == 1 then
    return 1
  else
    return 1, 2
  end
end

然后,我想构建另一个调用ab的函数,并返回a的所有结果,然后是b的所有结果。我想写这样的东西:

function c(num)
  return a(num), b(num)
end

但它只返回a的第一个结果,然后是b的所有结果。我该怎么做?

2 个答案:

答案 0 :(得分:4)

您只能返回表达式列表中最后一个函数的所有结果;其他人将被截断为一个结果。

结果,这个

function f1()
    return 1
end

function f2()
    return 2, 3
end

print(f1(), f2())

按预期打印1 2 3,但是

print(f2(), f1())

打印2 1,因为f2()被截断为一个结果。

作为一种解决方法,如果您提前了解结果数量,则可以

local a, b = f1()
local c, d = f2()
return a, b, c, d

或者对于任意数量的结果,您可以

local t1 = {f1()}
local t2 = {f2()}
-- Append t2 to t1
return unpack(t1)

答案 1 :(得分:1)

将列表扩展到列表上下文时,只使用第一个项目,或者,如果在列表上下文的末尾进行扩展,则使用所有项目。 (对不起,对于Perl-ish术语。)

您可以捕获表构造函数{ a(num) }中的所有列表项。由于列表已扩展为列表上下文中的最后一项,因此将使用所有项目。

回到另一个方向,您可以使用unpack功能将表格缩减为列表。但是,它使用表“长度”概念,该概念仅适用于连续序列数组。由于函数结果可能包含nil,因此您必须通过计数来度量表中的项目数,并使用pairs函数迭代表。

local function a(num)
  if num == 1 then
    return 1
  else
    return nil, 2
  end
end    

local function b(num)
  if num == 1 then
    return 1
  else
    return nil, 2
  end
end

local function c(num)
    local t = {}
    local n = 0
    local bOffset = 0 
    for k, v in pairs({ a(num) }) do
        table.insert(t, k, v)
        if (k > n) then
            n = k
        end
        if (k > bOffset) then
            bOffset = k
        end
    end
    for k, v in pairs({ b(num) }) do
        table.insert(t, bOffset + k, v)
        if (bOffset + k > n) then
            n = bOffset + k
        end
    end

    return unpack(t, 1, n) 
end
print(nil,2,nil,2)
print(c(0202))