Lua學習——閉包、迭代器

copy:http://blog.csdn.net/phenix32/article/details/8961592

--[[
 時間:2013年5月22日11:25:40
 作者:PhoenixCao
 內容:Lua程序練習3
--]]
-- 閉包示例
names = {"Peter","Phoenix","Mary"}
grades = {Mary = 10, Peter = 7, Phoenix = 8}
table.sort(names,function (n1,n2)
 return grades[n1] > grades[n2]
end)
for i = 1, #names do
 print(names[i])
end
--[[ 輸出結果
Mary
Phoenix
Peter
--]]

-- 閉包是對值的理解,不是函數
function newCounter()
 local i = 0
 return function()  -- 匿名函數
  i = i + 1
  return i
 end
end
c1 = newCounter()
c2 = newCounter()
print(c1)     -- 函數指針的所在地址
print(c1())     -- 函數的返回值
print(c1())
print(c2())
--[[ 輸出結果
function: 0041C060
1
2
1
--]]

-- 迭代器測試
function list_iter(tbl)
 local i = 0
 local n = table.getn(tbl)
 return function()
  i = i + 1
  if i <= n then return tbl[i] end
 end
end
t = {10,20,30}
iter = list_iter(t)
while true do
 local element = iter()   -- 調用其函數
 if element == nil then break end
 print(element)
end
for element in list_iter(t) do
 print(element)
end
--[[ 輸出結果
10
20
30
10
20
30
--]]

--[[
function allwords()
 local line = io.read()
 local pos = 1
 return function()
  while line do
   local s,e = string.find(line,"%w+",pos)
   if s then -- 找到了起始位置
    pos = e + 1
    return string.sub(line,s,e)
   else -- 沒找到接着找下一行,從頭開始
    line = io.read()
    pos = 1
   end
  end
 return nil  -- 文件查找結束
 end
end

for word in allwords() do
 print(word)
end
--]]
--[[ 輸入lala la l
輸出結果
lala
la
l
--]]

-- 我們要儘量使用無狀態的迭代器,因爲這樣循環的時候由for來保存,
-- 無需要創建對象,花費的代價小,如果不能用無狀態的迭代器實現,
-- 應儘可能使用閉包,盡少使用table,因爲閉包的代價比創建table要小,
-- 閉包處理速度也比table要快,還可以使用協同來創建迭代器方式。
--(注意:對於for結構來說,狀態常量沒有用處,僅僅在初始化時獲取他的值並傳遞給迭代函數)
function iter (a, i)
 i = i + 1
 local v = a[i]
 if v then 
 return i, v  --迭代函數返回2個值  索引與值
 end
end
function ipairs (a) --ipairs lua簡單實現
 return iter, a, 0 --返回3個值  迭代函數,狀態常量a,控制變量初始值0
end
a = {"one", "two", "three"}
--無狀態的迭代器是指不保留任何狀態的迭代器,不訪問外部函數變量
--因此在循環中我們可以利用無狀態迭代器避免創建閉包花費額外的代價。
for i, v in ipairs(a) do --無狀態迭代?  完成迭代功能的是for語句
 print(i, v)
end
--[[ 輸出結果
1 one
2 two
3 three
--]]

 

發佈了6 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章