function newCounter() local i = 0 return function() -- anonymous function i = i + 1 return i endendc1 = newCounter()print(c1()) --> 1print(c1()) --> 2c2 = newCounter()print(c2()) --> 1print(c1()) --> 3print(c2()) --> 2print(newCounter()()) --> 1print(newCounter()()) --> 1print(newCounter()()) --> 1
P.S::如果返回的是匿名函數,則需要再加一個()以調用匿名函數的內容
c1、c2 是建立在同一個函數上,但作用在同一個局部變數的不同執行個體上的兩個不同的閉包。
技術上來講,閉包指值而不是指函數,函數僅僅是閉包的一個原型聲明;儘管如此,在不會導致混淆的情況下我們繼續使用術語函數代指閉包。
閉包在上下文環境中提供很有用的功能,如前面我們見到的可以作為進階函數(sort)的參數;作為函數嵌套的函數(newCounter)。這一機制使得我們可以在 Lua 的函數世界裡組合出奇幻的編程技術。閉包也可用在回呼函數中,比如在 GUI 環境中你需要建立一系列 button,但使用者按下 button 時回呼函數被調用,可能不同的按鈕被按下時需要處理的任務有點區別。具體來講,一個十進位計算機需要 10 個相似的按鈕,每個按鈕對應一個數字,可以使用下面的函數建立他們:
function digitButton (digit) return Button{ label = digit, action = function () add_to_display(digit) end } end
這個例子中我們假定 Button 是一個用來建立新按鈕的工具, label 是按鈕的標籤,action 是按鈕被按下時調用的回呼函數。(實際上是一個閉包,因為他訪問 upvalue digit)。digitButton 完成任務返回後,局部變數 digit 超出範圍,回呼函數add_to_display仍然可以被調用並且可以訪問局部變數
digit。