这篇文章主要介绍了Lua教程(五):迭代器和泛型for,本文讲解了迭代器与Closure、泛型for的语义、 无状态迭代器的例子、 具有复杂状态的迭代器等内容,需要的朋友可以参考下
1. 迭代器与Closure:
在Lua中,迭代器通常为函数,每调用一次函数,即返回集合中的“下一个”元素。每个迭代器都需要在每次成功调用之间保持一些状态,这样才能知道它所在的位置和下一次遍历时的位置。从这一点看,Lua中closure机制为此问题提供了语言上的保障,见如下示例:
function values(t)
local i = 0
return function()
i = i + 1
return t[i]
end
end
t = {10, 20, 30}
it = values(t)
while true do
local element = it()
if element == nil then
break
end
print(element)
end
--另外一种基于foreach的调用方式(泛型for)
t2 = {15, 25, 35}
for element in values(t2) do
print(element)
end
--输出结果为:
--10
--20
--30
--15
--25
--35
从上面的应用示例来看,相比于while方式,泛型for的方式提供了更清晰的实现逻辑。因为Lua在其内部替我们保存了迭代器函数,并在每次迭代时调用该隐式的内部迭代器,直到迭代器返回nil时结束循环。
2. 泛型for的语义:
上面示例中的迭代器有一个明显的缺点,即每次循环时都需要创建一个新的closure变量,否则第一次迭代成功后,再将该closure用于新的for循环时将会直接退出。
这里我们还是先详细的讲解一下Lua中泛型(for)的机制,之后再给出一个无状态迭代器的例子,以便于我们的理解。如果我们的迭代器实现为无状态迭代器,那么就不必为每一次的泛型(for)都重新声明一个新的迭代器变量了。
泛型(for)的语法如下:
for
end
为了便于理解,由于我们在实际应用中
function ipairs2(a)
return iter,a,0
end
该函数返回3个值,第一个为实际的迭代器函数变量,第二个是一个恒定对象,这里我们可以理解为待遍历的容器,第三个变量是在调用iter()函数时为其传入的初始值。
下面我们再看一下iter()函数的实现,如:
local function iter(a, i)
i = i + 1
local v = a[i]
if v then
return i, v
else
return nil, nil
end
end
在迭代器函数iter()中返回了两个值,分别对应于table的key和value,其中key(返回的i)如果为nil,泛型(for)将会认为本次迭代已经结束。下面我们先看一下实际用例,如:
function ipairs2(a)
return iter,a,0
end
local function iter(a, i)
i = i + 1
local v = a[i]
if v then
return i, v
else
return nil, nil
end
end
a = {"one","two","three"}
for k,v in ipairs2(a) do
print(k, v)
end
--输出结果为:
--1 one
--2 two
--3 three
以上就是Lua教程(五):迭代器和泛型for的详细内容,更多请关注0133技术站其它相关文章!