function createCountdownTimer(second)
local ms=second * 1000;
local function countDown()
ms = ms - 1;
return ms;
end
return countDown;
end
timer1 = createCountdownTimer(1);
for i=1,3 do
print(timer1());
end
print("------------");
timer2 = createCountdownTimer(1);
for i=0,2 do
print(timer2());
end
在前面的代碼中,函數countDown使用的定義在函數createCountdownTimer中的局部變量ms就是countDown的upvalue,但ms對createCountdownTimer而言只是一個局部變量,不是upvalue。Upvalue是Lua不同于C/C++的特有屬性,需要結合代碼仔細體會。
閉包是一個內部函數,它可以訪問一個或者多個外部函數的外部局部變量。每次閉包的成功調用后這些外部局部變量都保存他們的值(狀態)。當然如果要創建一個閉包必須要創建其外部局部變量。所以一個典型的閉包的結構包含兩個函數:一個是閉包自己;另一個是工廠(創建閉包的函數)。迭代器需要保留上一次成功調用的狀態和下一次成功調用的狀態,也就是他知道來自于哪里和將要前往哪里。閉包提供的機制可以很容易實現這個任務。
function create(name,id)
local data={name = name,id=id};
local obj={};
function obj.GetName()
return data.name;
end
function obj.GetID()
return data.id;
end
function obj.SetName(name)
data.name=name;
end
function obj.SetID(id)
data.id=id
end
return obj;
end
o1 = create("Sam", 001)
o2 = create("Bob", 007)
o1.SetID(100)
print("o1's id:", o1.GetID(), "o2's id:",o2.GetID())
o2.SetName("Lucy")
print("o1's name:", o1.GetName(),"o2's name:", o2.GetName())
--o1's id: 100 o2's id: 7
--o1's name: Sam o2's name: Lucy
t = {}
m = { a = " and ", b = "Li Lei", c = "Han Meimei" }
setmetatable(t, { __index = m}) --表{ __index=m }作為表t的元表
for k, v in pairs(t) do --窮舉表t
print(v)
end
print("-------------")
print(t.b, t.a, t.c)
--輸出結果
---------------
--Li Lei and Han Meimei
function add(t1, t2)
--‘#'運算符取表長度
assert(#t1 == #t2)
local length = #t1
for i = 1, length do
t1[i] = t1[i] + t2[i]
end
return t1
end
--setmetatable返回被設置的表
t1 = setmetatable({ 1, 2, 3}, { __add = add })
t2 = setmetatable({ 10, 20, 30 }, {__add = add })
t1 = t1 + t2
for i = 1, #t1 do
print(t1[i])
end
--11
--22
--33