同步發表於個人網站
對於一個變數,Lua會先嘗試從當前詞法環境(Lexical)尋找,再從當前環境中尋找(
_ENV
)。
那的對於區塊變數呢??
function parentFunction()
local L1 = 100
local function childFunction()
print("here is child")
end
return childFunction
end
f1 = parentFunction(100)
f1() -- Output: here is child
上例中,區塊變數L1
沒有任何人可以存取的到,簡直消失在了時空夾縫之中。
詞法環境(Lexical)指的是程式編寫當下,執行區塊由內而外,可以見到的範圍。
在Lua變數預設值為nil
。透過查找規則,可以暫時隱藏一切區塊變數。
do
local L1 = 100
do
local L1 = nil
do -- 隱藏的區塊
print(L1) -- Output: nil
end
end
print(L1) -- Output: 100
end
這種奇淫的技巧沒什麼作用,不過卻可以幫助我們理解變數的查找。
function createFunTable()
local T = {}
do
local L1 = 100
function T.f1()
print(L1)
end
end
do
local L1 = 200
function T.f2()
print(L1)
end
end
return T
end
T = createFunTable()
T.f1() -- Output: 100
T.f2() -- Output: 200
不過上面寫法還不如:
function createFunTable()
local T = {}
function T.f1()
local L1 = 100
print(L1)
end
function T.f2()
local L1 = 200
print(L1)
end
return T
end
T = createFunTable()
T.f1() -- Output: 100
T.f2() -- Output: 200
在下例中,X
只有提供的getX()
和setX()
可以存取。
do
local X = 1
function getX()
return X
end
function setX(v)
X = v
return X
end
end
print(X) -- Output: nil
print(getX()) --> 1
setX(100)
print(getX()) --> 100
如果不提供setX()
,X
就是一個唯獨變數。
do
local X<const> = 1
function getX()
return X
end
end
print(X) -- Output: nil
print(getX()) --> 1
現在,可以來寫一個可以產生一個擁有特殊區塊變數函數的函數。這就是閉包的用法。
好饒舌
我們寫一個makeAdd(n)
,其會得到一個函數允許傳入另一個參數k
,其結果為n+k
:
function makeAdd(n)
local n = n
return function (k)
return n + k
end
end
add5 = makeAdd(5)
print(add5(3)) -- Output: 8
如果你已經了解變數查找的方式,上面例子應該不難。