因爲函數是一種「第一類值」,所以一個顯而易見的推論就是,函數不只能夠存儲在全局變量中,還能夠存儲在table的字段和局部變量中。函數
大部分Lua庫也採用了這種將函數存儲在字段中的機制(io.read、math.sin).若要在Lua中建立這種函數,只需將常規的函數語法與table語法結合起來使用便可: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 } 還可使用另外一種語法來定義這類函數: lib = {} function lib.foo (x, y) return x + y end function lib.goo (x, y) return x - y end
只要將一個函數存儲到一個局部變量中,即獲得了一個「局部函數」,也就是說該函數只能在某個特定的做用域中使用。spa
由於Lua是將每一個程序塊做爲一個函數來處理的,因此在一個程序塊中聲明的函數就是局部函數,這些局部函數只在該程序塊中可見。「詞法域」確保了程序包中的其餘函數可使用這些局部函數:code
local f = function(參數) <函數體> end local g = function(參數) <一些代碼> f() -- f在這裏是可見的。 <一些代碼> end 對於這種局部函數的定義,Lua還支持一種「語法糖」: local function f(參數) <函數體> end 在定義遞歸的局部函數時,像下面這種函數的定義語法是錯誤的: local fact = function (n) if n == 0 then return 1 else return n*fact(n -1) end end 由於,當Lua編譯到函數體中調用fact(n-1)的地方時,因爲局部的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 foo(參數) <函數體> end Lua將其展開爲: local foo foo = function(參數) <函數體> end 使用這種語法來定義遞歸函數不會產生錯誤: local function fact(n) if n == 0 then return 1 else return n*fact(n - 1) end end 然而,在間接遞歸的狀況中,必須使用一個明確的前向聲明: local f, g --前向聲明 function g () <一些代碼> f() <一些代碼> end function f () <一些代碼> g() <一些代碼> end 注意:別把第二個函數定義寫爲「local function f」.若是那樣的話,Lua會建立一個全新的局部變量f,而將原來聲明的f置於未定義的狀態。