最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解讀Lua中迭代器與泛型for的使用

 更新時間:2016年06月17日 15:33:54   作者:林壽山  
在Lua中,迭代器常被寫為函數而被調用返回下一個元素,而for循環(huán)調用迭代器函數則使得迭代更強強大,下面我們就來深入解讀Lua中迭代器與泛型for

泛型for原理

迭代器是一種可以遍歷集合中所有元素的機制,在Lua中通常將迭代器表示為函數,每調用一次函數,就返回集合中“下一個”元素。每個迭代器都需要在每次成功調用之間保持一些狀態(tài),這樣才能知道它所在的位置及如何步進到下一個位置,closure就可以完成此項工作。下面的示例是列表的一個簡單的迭代器:

function values(t)
 local i = 0
 return function() i = i + 1; return t[i] end
end

循環(huán)調用:

t = {10, 20, 30}
iter = values(t)
while true do
 local el = iter()
 if el == nil then break end
 print(el)
end

泛型for調用

for el in values(t) do print(el) end

泛型for為一次迭代循環(huán)做了所有的簿記工作。它在內部保存了迭代器函數,并在每次迭代時調用迭代器,在迭代器返回nil時結束循環(huán)。實際上泛型for保存了3個值:迭代器函數f、恒定狀態(tài)s、控制變量a。for做的第一件事就是對in后面的表達式求值,并返回3個值供for保存;接著for會以s和a來調用f。在循環(huán)過程中控制變量的值依次為a1 = f(s, a0),a2 = f(s, a1),依次類推,直至ai為nil結束循環(huán)。

先看一段代碼

for element in list_iter(t) do 
 print(element) 
end 

在不往下看之前,我們可以先試圖根據我們已有的知識結構去理解這段代碼。如果這樣,list_iter(t)應該返回一個類似集合的東西,而我們已經知道實際上只返回了一個匿名函數,也就是迭代器。當然,每次調用迭代器都可以得到一個元素,迭代器的所有的結果倒是可以看成一個集合。因素齊了,我們需要一個邏輯上的解釋,這個邏輯就是 泛型for的語義。
先看文法規(guī)定:

for <var-list> in <exp-list> do 
 <body> 
end 

整個過程是這樣的:
首先,初始化,計算 in 后面表達式的值,表達式應該返回 泛型for 需要的三個值:迭代函數、狀態(tài)常量、控制變量;與多值賦值一樣,如果表達式返回的結果個數不足三個會自

動用nil 補足,多出部分會被忽略。
第二,將狀態(tài)常量和控制變量作為參數調用迭代函數(注意:對于 for 結構來說,狀態(tài)常量沒有用處,僅僅在初始化時獲取他的值并傳遞給迭代函數)。

第三,將迭代函數返回的值賦給變量列表。
第四,如果返回的第一個值為 nil 循環(huán)結束,否則執(zhí)行循環(huán)體。
第五,回到第二步再次調用迭代函數。

更具體地說:

for var_1, ..., var_n in explist do block end 

等價于

do 
 local _f, _s, _var = explist 
 while true do 
  local var_1, ... , var_n = _f(_s, _var) 
  _var = var_1 
  if _var == nil then break end 
  block 
 end 
end 

 泛型 for 在自己內部保存三個值:迭代函數、狀態(tài)常量、控制變量。

迭代器的狀態(tài)

無狀態(tài)的迭代器本身不保存任何狀態(tài),for循環(huán)只會用恒定狀態(tài)和控制變量來調用迭代器函數。這類迭代器典型例子就是ipairs,下面是ipairs的Lua實現:

local function iter(s, i)
 i = i + 1
 local v = s[i]
 if v then return i, v end
end
function ipairs(s)
 return iter, s, 0
end

當for循環(huán)調用ipairs(list)時,會獲得3個值,然后Lua調用iter(list, 0)得到list, list[1],調用iter(list, 1)得到list, list[2],知道得到一個nil為止。

雖然泛型for只提供一個恒定狀態(tài)和一個控制變量用于狀態(tài)的保存,但有時需要保存許多其他狀態(tài)。這時可以用closure來保存,或者將所需的狀態(tài)打包為一個table,并保存在恒定狀態(tài)中。

閉包、迭代器和泛型for

到現在,Lua為我們準備了三塊積木:閉包、泛型for和迭代器。一個循環(huán),我們可以利用閉包+迭代器,也可以使用泛型for+迭代器。那我們該怎么取舍呢?Lua也給出了建

議。

function iter (a, i) 
 i = i + 1 
 local v = a[i] 
 if v then 
  return i, v 
 end 
end 
 
function ipairs (a) 
 return iter, a, 0 
end 
 
for i, v in ipairs(a) do 
 print(i, v) 
end 

這種情況是Lua最推薦的,迭代器不依賴upvalue,不產生閉包,狀態(tài)常量和控制變量借助泛型for保存,通過迭代器的參數傳遞給了迭代器。
再給一個書中的例子:

local iterator -- to be defined later 
 
function allwords() 
 local state = {line = io.read(), pos = 1} 
 return iterator, state 
end 
 
function iterator (state) 
 while state.line do -- repeat while there are lines 
  -- search for next word 
  local s, e = string.find(state.line, "%w+", state.pos) 
  if s then -- found a word? 
   -- update next position (after this word) 
   state.pos = e + 1 
   return string.sub(state.line, s, e) 
  else -- word not found 
   state.line = io.read() -- try next line... 
   state.pos = 1 -- ... from first position 
  end 
 end 
 return nil -- no more lines: end loop 
end 

這樣好不好呢,Lua給的答案是否定的。書中有一段話說得很清楚:
我們應該盡可能的寫無狀態(tài)的迭代器,因為這樣循環(huán)的時候由for 來保存狀態(tài),不需要創(chuàng)建對象花費的代價??;如果不能用無狀態(tài)的迭代器實現,應盡可能使用閉包;盡可能不

要使用table 這種方式,因為創(chuàng)建閉包的代價要比創(chuàng)建table 小,另外Lua 處理閉包要比處理table 速度快些。

相關文章

  • Lua和C++語言的交互詳解

    Lua和C++語言的交互詳解

    這篇文章主要介紹了Lua和C++語言的交互詳解,本文講解了C++和Lua交互,涉及到獲取Lua中普通變量的值,Lua中table的值和調用Lua中的函數,需要的朋友可以參考下
    2014-09-09
  • Cocos2d-x中調用Lua及HelloWorld.lua源碼分解

    Cocos2d-x中調用Lua及HelloWorld.lua源碼分解

    這篇文章主要介紹了Cocos2d-x中調用Lua及HelloWorld.lua源碼分解,本文最后總結了一些Lua的語法,需要的朋友可以參考下
    2014-09-09
  • Lua教程(十四):字符串庫詳解

    Lua教程(十四):字符串庫詳解

    這篇文章主要介紹了Lua教程(十四):字符串庫詳解,本文講解了基礎字符串函數、模式匹配函數、模式、捕獲(capture):、替換等內容,需要的朋友可以參考下
    2015-04-04
  • Lua字符串庫(string庫)學習筆記

    Lua字符串庫(string庫)學習筆記

    這篇文章主要介紹了Lua字符串庫(string庫)學習筆記,本文列舉了一些常用的Lua字符串庫函數,如byte、char、dump、find等,需要的朋友可以參考下
    2014-12-12
  • Lua中..和#運算符的使用方法

    Lua中..和#運算符的使用方法

    這篇文章主要介紹了Lua中..和#運算符的使用方法,是Lua入門學習中的基礎知識,需要的朋友可以參考下
    2015-05-05
  • Lua中的函數精講筆記

    Lua中的函數精講筆記

    這篇文章主要介紹了Lua中的函數精講筆記,本文講解了函數的用途、可變參數函數、閉包、非全局函數等內容,需要的朋友可以參考下
    2015-04-04
  • Lua基礎教程之表(Table)學習筆記

    Lua基礎教程之表(Table)學習筆記

    這篇文章主要介紹了Lua基礎教程之表(Table)學習筆記,本文來自個人總結,需要的朋友可以參考下
    2014-09-09
  • Lua中的for循環(huán)和迭代器的秘密探究

    Lua中的for循環(huán)和迭代器的秘密探究

    這篇文章主要介紹了Lua中的for循環(huán)和迭代器的秘密探究,本文講解了返回兩個值的迭代器、for .. in .. do的真面目、迭代器函數、恒定狀態(tài)、控制變量初值等內容,需要的朋友可以參考下
    2014-09-09
  • 詳解Lua中的變量相關知識點

    詳解Lua中的變量相關知識點

    這篇文章主要介紹了Lua中的變量相關知識點,是Lua入門中的基礎知識,需要的朋友可以參考下
    2015-05-05
  • Lua中操作字符串的基本方法整理

    Lua中操作字符串的基本方法整理

    這篇文章主要介紹了Lua中操作字符串的基本方法整理,是Lua入門學習中的基礎知識,需要的朋友可以參考下
    2015-05-05

最新評論

五河县| 绥滨县| 上林县| 稷山县| 泰和县| 南康市| 广饶县| 乌兰察布市| 鸡东县| 青龙| 西和县| 安岳县| 富平县| 易门县| 稷山县| 衡东县| 宜州市| 彩票| 兴安盟| 湖北省| 阳东县| 柳江县| 万宁市| 平远县| 揭西县| 茂名市| 潜江市| 卢氏县| 渝中区| 翁牛特旗| 大宁县| 彰化县| 民勤县| 印江| 拜城县| 宁远县| 北票市| 旺苍县| 鸡西市| 德阳市| 昌平区|