此第一版是為 Lua 5.0 編寫的。儘管對後續版本仍然有很大的關聯性,但仍有一些區別。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買此書,您還可以幫助 支持 Lua 項目


5.2 – 可變數量的參數

Lua 中的一些函數接收可變數量的參數。例如,我們已經使用一個、兩個和更多參數呼叫了 print

現在假設我們想在 Lua 中重新定義 print:也許我們的系統沒有 stdout,因此 print 沒有列印其參數,而是將它們儲存在一個全域變數中,以便以後使用。我們可以用 Lua 編寫這個新函數,如下所示

    printResult = ""
    
    function print (...)
      for i,v in ipairs(arg) do
        printResult = printResult .. tostring(v) .. "\t"
      end
      printResult = printResult .. "\n"
    end
參數列表中的三個點(...)表示函數有可變數量的參數。當呼叫此函數時,其所有參數都收集到一個單一表格中,函數以一個名為 arg 的隱藏參數的形式訪問該表格。除了這些參數外,arg 表格還有一個額外的欄位 n,其中包含收集到的實際參數數量。

有時,一個函數有一些固定參數加上可變數量的參數。讓我們看一個例子。當我們編寫一個函數將多個值傳回表達式時,只使用其第一個結果。但是,有時我們想要另一個結果。一個典型的解決方案是使用虛擬變數;例如,如果我們只想要 string.find 的第二個結果,我們可以編寫以下程式碼

    local _, x = string.find(s, p)
    -- now use `x'
    ...
另一種解決方案是定義一個 select 函數,它從函數中選擇一個特定的回傳值
    print(string.find("hello hello", " hel"))         --> 6  9
    print(select(1, string.find("hello hello", " hel"))) --> 6
    print(select(2, string.find("hello hello", " hel"))) --> 9
請注意,對 select 的呼叫總有一個固定參數,即選擇器,加上可變數量的額外參數(函數的回傳值)。為了容納這個固定參數,一個函數可以在點之前有常規參數。然後,Lua 將前幾個參數分配給這些參數,只有額外的參數(如果有)傳遞給 arg。為了更好地說明這一點,假設有一個定義如下
    function g (a, b, ...) end
然後,我們有以下從參數到參數的對應關係
    CALL            PARAMETERS
       
    g(3)             a=3, b=nil, arg={n=0}
    g(3, 4)          a=3, b=4, arg={n=0}
    g(3, 4, 5, 8)    a=3, b=4, arg={5, 8; n=2}

使用這些常規參數,select 的定義非常簡單

    function select (n, ...)
      return arg[n]
    end

有時,一個具有可變數量的參數的函數需要將它們全部傳遞給另一個函數。它所要做的就是使用 unpack(arg) 作為參數呼叫另一個函數:unpack 將傳回 arg 中的所有值,這些值將傳遞給另一個函數。此用法的良好範例是一個用於撰寫格式化文字的函數。Lua 提供了單獨的函數來格式化文字(string.format,類似於 C 函式庫中的 sprintf 函數)和撰寫文字(io.write)。當然,可以輕鬆地將這兩個函數組合成一個函數,只不過這個新函數必須將可變數量的值傳遞給 format。這是 unpack 的工作

    function fwrite (fmt, ...)
      return io.write(string.format(fmt, unpack(arg)))
    end