Lua程序設計 迭代器與closure

          所謂「迭代器」就是一種能夠遍歷一種集合中全部元素的機制。在Lua中,一般將迭代器表示爲函數。每調用一次函數,即返回集合中的「下一個」元素。函數

         每一個迭代器都須要在每次成功調用之間保持一些狀態,這樣才能知道它所在的位置及如何步進到下一個位置。在Lua中,closure對於這類任務提供了極佳的支持,一個closure就是一種能夠訪問其外部嵌套環境中的局部變量的函數。對於closure而言,這些變量就可用於在成功調用之間保持狀態值,從而使closure能夠記住它在一次遍歷中所在的位置。固然,爲了建立一個新的closure,還必須建立它的這些「非局部的變量」。所以,一個closure一般涉及到兩個函數:closure自己和一個用於建立該closure的工廠函數。lua

      示例:返回元素值的迭代器示例。spa

function values (table) 
  local i = 0
 return function () i = i + 1; return table[i] end
end
   本例中,values就是一個工廠,每當調用這個工廠時,它就建立一個新的closure(即迭代器自己)。這個closure將它的狀態保存在其外部變量table和i中。
每當調用這個迭代器時,它就從列表table中返回下一個值。直到最後一個元素返回後,迭代器就會返回nil,以此表示迭代器結束。

       能夠在while循環中使用這個迭代器:code

  table = {1,2,3}
  iter = values (table)   --建立迭代器
  while true do
     local element = iter()   --調用迭代器
        if element == nil then break end
     print(element)
  end
 ================================= 
  然而,使用泛型for則更加簡單
  table = {1,2,3}
   for element in values(table) do
     print(element)
   end
   
 泛型for爲一次迭代循環作了全部的簿記工做。它在內部保存了迭代器函數,所以再也不須要iter變量。它在每次新迭代時調用迭代器,並在迭代器返回nil時結束循環。

    示例:遍歷當前輸入文件中全部單詞element

  for word in allwords() do
    print()
  end
 對於迭代器,編寫迭代器自己或許不容易,但使用它們卻很容易。
 
 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 = s + 1 --該單詞的下一個位置
             return string.sub(line, s, e)   --返回該單詞
            else
               line = io.read() --沒有找到單詞,嘗試下一行
               pos =1           --在第一個位置上,從新開始
            end
            end
           return  nil            -- 沒有其他行了,遍歷結束
      end
 end
相關文章
相關標籤/搜索