2014-01-09 52 views
3

假設我有兩個可變參數的功能是這樣的:組合兩個可變參數函數導致

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的結果。我將如何做到這一點?

回答

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

當展開列表到列表上下文中,或者只使用第一個項目,或者如果擴展發生在列表上下文的末尾,則使用所有項目。 (對不起,對於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))