Lua學習筆記(7)

 今天繼續學習函數的高級內容:web

 

6. More about Functions
1)函數名是變量,能夠賦值,傳遞,做爲函數的返回值
     如圖:

2)匿名函數:
     Lua容許匿名函數:如
     f = function (x) return 2*x end  -->建立了一個匿名函數,並將函數賦值給變量f

3)高級函數:
     在Lua中,用其餘函數的名稱做爲輸入參數的函數,叫作高級函數。
     做爲輸入參數的函數名,和通常的變量使用方式相同, 如:
     
或者:

 
4)閉包:
     函數嵌套時:內部函數能夠訪問外部函數的變量,這個變量稱做外部的局部變量:external local variable 或者 upvalue
     如圖所示:
 

     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語句,而不是通常的函數加棧調用方式。
相關文章
相關標籤/搜索