今天繼續學習函數的高級內容:web
6. More about Functions
1)函數名是變量,能夠賦值,傳遞,做爲函數的返回值
如圖:
![](http://static.javashuo.com/static/loading.gif)
2)匿名函數:
Lua容許匿名函數:如
f = function (x) return 2*x end -->建立了一個匿名函數,並將函數賦值給變量f
3)高級函數:
在Lua中,用其餘函數的名稱做爲輸入參數的函數,叫作高級函數。
做爲輸入參數的函數名,和通常的變量使用方式相同, 如:
或者:
![](http://static.javashuo.com/static/loading.gif)
4)閉包:
函數嵌套時:內部函數能夠訪問外部函數的變量,這個變量稱做外部的局部變量:external local variable 或者 upvalue
如圖所示:
![](http://static.javashuo.com/static/loading.gif)
i是Count的局部變量,在內嵌的匿名函數中被訪問,每次遞增一
注意:
(1)直接打印print(Cn()),打印的是內嵌函數的地址。
(2)c1 = Cn(),表示將Cn的內嵌函數付給了c1。和 c1 = Cn徹底不一樣含義。
(3)c1只是Cn()內嵌函數的變量,但其中用到了Cn的局部變量i,則經過Lua的閉包機制,在c1中創建了一個i的實例。
(4)建立了兩個Cn()的實例,c1和c2,他們擁有各自獨立的外部局部變量i,他們的計數是相互獨立的。
從技術上講,閉包是值,而不是函數,有點相似於創建了一個類的實例,其中的upvalue都有本身的一個實例。
閉包技術能夠做爲一種沙箱實現,來建立安全的環境,把不安全代碼放在一個閉包中,來限制訪問的方式。
5)表的函數:
(1)對錶,能夠添加表對應的函數,如:
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
這種方式相似於C語言中給結構體加函數的方式。
6)局部函數:
將函數賦值給局部變量,能夠限制函數的方位範圍。如:
local f = function(x) return 2*x end 則,函數只能在f的做用域中使用。
或者,
local function f(x) return 2*x end 和上述的做用相同
對遞歸函數須要先聲明局部函數,不然Lua會找不到相應的函數,如:
local fact
fact = function (n)
if n <= 0 then return 1
else return n*fact(n-1) end
end
7)尾調用(尾遞歸 Tail Calls)
function f()
return g()
end
當調用g()後不須要返回f(),則系統不須要保存f()的上下文,這種狀況就稱爲尾調用。
這時,Lua不會再增長額外的棧來放置被調用的函數g(),在遞歸時能有效的防止棧溢出。
如:
function f(n)
if n > 0 then return f(n-1) end
end
這時不論n多大,Lua調用時都不會將f層層加棧。
能夠講尾調用當作一個goto語句,而不是通常的函數加棧調用方式。