第一版是針對 Lua 5.0 編寫的。雖然在很大程度上仍然適用於後續版本,但有些地方有所不同。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買這本書,您也同時 贊助了 Lua 專案


6.2 – 非全域函式

一級函式的明顯結果是,我們不僅可以將函式儲存在全域變數中,還可以將函式儲存在表格欄位和區域變數中。

我們已經看過表格欄位中函式的幾個範例:大多數 Lua 函式庫都使用此機制(例如,io.readmath.sin)。要在 Lua 中建立此類函式,我們只需要將函式和表格的常規語法組合在一起

    Lib = {}
    Lib.foo = function (x,y) return x + y end
    Lib.goo = function (x,y) return x - y end
當然,我們也可以使用建構函式
    Lib = {
      foo = function (x,y) return x + y end,
      goo = function (x,y) return x - y end
    }
此外,Lua 還提供另一種語法來定義此類函式
    Lib = {}
    function Lib.foo (x,y)
      return x + y
    end
    function Lib.goo (x,y)
      return x - y
    end
最後一個片段與第一個範例完全相同。

當我們將函式儲存在區域變數中時,我們會得到一個區域函式,也就是說,一個函式會限制在特定範圍內。此類定義對於套件特別有用:由於 Lua 將每個區塊視為函式,因此區塊可以宣告區域函式,而這些函式只會在區塊內部可見。詞彙範圍確保套件中的其他函式可以使用這些區域函式

    local f = function (...)
      ...
    end
    
    local g = function (...)
      ...
      f()   -- external local `f' is visible here
      ...
    end
Lua 支援使用區域函式的語法糖
    local function f (...)
      ...
    end

在遞迴區域函式的定義中出現了一個微妙的重點。天真的方法在此處不起作用

    local fact = function (n)
      if n == 0 then return 1
      else return n*fact(n-1)   -- buggy
      end
    end
當 Lua 編譯函式主體中的呼叫 fact(n-1) 時,區域 fact 尚未定義。因此,該表達式會呼叫全域 fact,而不是區域 fact。要解決這個問題,我們必須先定義區域變數,然後再定義函式
    local fact
    fact = function (n)
      if n == 0 then return 1
      else return n*fact(n-1)
      end
    end
現在函式內的 fact 參照區域變數。函式定義時的其值並不重要;函式執行時,fact 已經具有正確的值。這是 Lua 擴充其區域函式語法糖的方式,因此您可以放心將其用於遞迴函式
    local function fact (n)
      if n == 0 then return 1
      else return n*fact(n-1)
      end
    end
當然,如果您有間接遞迴函數,這個技巧就不管用了。在這種情況下,您必須使用顯式前向宣告的等效項
    local f, g    -- `forward' declarations
    
    function g ()
      ...  f() ...
    end
    
    function f ()
      ...  g() ...
    end