国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Lua - 深入解讀Lua中迭代器與泛型for的使用

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

2020-05-07 11:27林壽山 Lua

在Lua中,迭代器常被寫為函數而被調用返回下一個元素,而for循環調用迭代器函數則使得迭代更強強大,下面我們就來深入解讀Lua中迭代器與泛型for

泛型for原理

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

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

循環調用:

?
1
2
3
4
5
6
7
t = {10, 20, 30}
iter = values(t)
while true do
 local el = iter()
 if el == nil then break end
 print(el)
end

泛型for調用

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

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

先看一段代碼

?
1
2
3
for element in list_iter(t) do
 print(element)
end

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

?
1
2
3
for <var-list> in <exp-list> do
 <body>
end

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

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

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

更具體地說:

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

等價于

?
1
2
3
4
5
6
7
8
9
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 在自己內部保存三個值:迭代函數、狀態常量、控制變量。

迭代器的狀態

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

?
1
2
3
4
5
6
7
8
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循環調用ipairs(list)時,會獲得3個值,然后Lua調用iter(list, 0)得到list, list[1],調用iter(list, 1)得到list, list[2],知道得到一個nil為止。

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

閉包、迭代器和泛型for

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

議。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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,不產生閉包,狀態常量和控制變量借助泛型for保存,通過迭代器的參數傳遞給了迭代器。
再給一個書中的例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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給的答案是否定的。書中有一段話說得很清楚:
我們應該盡可能的寫無狀態的迭代器,因為這樣循環的時候由for 來保存狀態,不需要創建對象花費的代價?。蝗绻荒苡脽o狀態的迭代器實現,應盡可能使用閉包;盡可能不

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

延伸 · 閱讀

精彩推薦
  • LuaLua實現__add方法重載示例

    Lua實現__add方法重載示例

    這篇文章主要介紹了Lua實現__add方法重載示例,本文直接給出實現代碼,需要的朋友可以參考下 ...

    腳本之家7452020-04-24
  • LuaLua簡介、編譯安裝教程及變量等語法介紹

    Lua簡介、編譯安裝教程及變量等語法介紹

    這篇文章主要介紹了Lua簡介、編譯安裝教程及變量等語法介紹,本文同時講解了lua注釋語法、Lua命令行方式等內容,需要的朋友可以參考下 ...

    junjie3632020-04-14
  • Lua深入探究Lua中的解析表達式

    深入探究Lua中的解析表達式

    這篇文章主要介紹了深入探究Lua中的解析表達式,對于其語法部分的說明和示例都超詳細,極力推薦此文!需要的朋友可以參考下 ...

    腳本之家3542020-05-05
  • LuaLua中table庫函數方法介紹

    Lua中table庫函數方法介紹

    這篇文章主要介紹了Lua中table庫函數方法介紹,本文講解了concat、insert、maxn、remove、sort、foreachi等方法,需要的朋友可以參考下 ...

    腳本之家2502020-04-17
  • LuaLua教程(二):基礎知識、類型與值介紹

    Lua教程(二):基礎知識、類型與值介紹

    這篇文章主要介紹了Lua教程(二):基礎知識、類型與值介紹,本文講解了Hello World程序、代碼規范、全局變量、類型與值等內容,需要的朋友可以參考下 ...

    腳本之家5922020-04-28
  • LuaLua中計算、執行字符串中Lua代碼的方法

    Lua中計算、執行字符串中Lua代碼的方法

    這篇文章主要介紹了Lua中計算、執行字符串中Lua代碼的方法,類似JavaScript中eval函數的功能,在Lua中也可以實現,需要的朋友可以參考下 ...

    腳本之家6322020-04-30
  • LuaLua和C語言的交互詳解

    Lua和C語言的交互詳解

    這篇文章主要介紹了Lua和C語言的交互詳解,Lua和C語言通過棧完成交互,本文結合代碼實例詳細講解了交互的方法,需要的朋友可以參考下 ...

    果凍想3702020-04-14
  • LuaLua中的元方法__newindex詳解

    Lua中的元方法__newindex詳解

    這篇文章主要介紹了Lua中的元方法__newindex詳解,本文講解了查詢與更新、監控賦值、通過table給另一個table賦值等內容,需要的朋友可以參考下 ...

    笨木頭8872020-04-09
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产精品第一国产精品 | 欧美日韩视频一区二区 | 国产精品永久免费视频 | 久久久成人精品 | 日本一区二区不卡在线观看 | 日本一区二区高清不卡 | 欧美日韩视频第一页 | 欧美三级视频 | 日韩欧美一区二区三区 | 日本一区二区高清视频 | 久久99国产精品免费网站 | 91亚洲成人| 精品亚洲一区二区三区四区五区 | 久久亚洲一区二区三区四区 | 久久久夜夜夜 | 国产欧美一区二区 | 成人免费毛片aaaaaa片 | 欧美区在线 | 欧美日韩精品一区二区三区四区 | 97色婷婷成人综合在线观看 | 久久久免费| 欧美色综合天天久久综合精品 | 国产成人无遮挡在线视频 | 国产视频色 | 亚洲免费观看 | 高清精品一区二区 | 亚洲日本网站 | 欧美视频三区 | 亚洲 综合 清纯 丝袜 自拍 | 欧美国产精品一区二区三区 | 欧美色综合天天久久综合精品 | 成人在线观看免费视频 | 亚洲一区二区三区四区五区午夜 | 中文字幕一区二区三区在线观看 | 视频在线一区二区 | 操av在线 | 亚洲日本欧美日韩高观看 | 精品国产乱码久久久久久图片 | 久久久久久亚洲av毛片大全 | 国产精品美女视频 | 精品久草|