Lua程序設計 非全局的函數

         因爲函數是一種「第一類值」,所以一個顯而易見的推論就是,函數不只能夠存儲在全局變量中,還能夠存儲在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置於未定義的狀態。
相關文章
相關標籤/搜索