首页 > 代码库 > Lua迭代器和泛型for

Lua迭代器和泛型for

1、迭代器与closure

在lua中,迭代器通常为函数,每调用一次函数,会返回集合中的下一个元素。每个迭代器在成功调用的时候,都需要保存一些状态,closure(闭包)完美为迭代器运用而生。

function values(t)    local i=0    return function() --匿名函数    i=i+1    return t[i]    endendt1 ={10, 20, 30}it=values(t1)   --创建闭包变量的参数为函数参数 while true do    local element=it()      --调用闭包时的参数为匿名函数的参数    if(element==nil) then break    end    print(element)endt2={11,22,33}for v in values(t2) do   print(v)end--输出结果--10--20--30--11--22--33

     从上面的例子可以看出,范型for相对于while给我们提供了更为清晰的实现逻辑。luo的内部函数已经为我们提供了迭代函数,运行foreach时我们会调用隐式的迭代器。

 

2、泛型for的语义

上面的迭代器有一个明显的缺点,就是每次循环时都要创建一个新的closure变量,而不能运用之前已经创建好了的closure变量,如果我在这个循环外再加一个循环进行迭代时,这就成了一个很繁琐并且容易出错的问题。

下面出现的迭代器很好的解决了这个问题,就不必为每次的泛型for都创建一个新的closure变量了。

function iter(a,i)   i=i+1   if a[i]==nil then return nil,nil   else return i,a[i]   endendfunction ipairs(a)   return iter,a,0         --iter在这里只是一个函数变量,并不是调用函数enda={"one","two","three"}for i,v in ipairs(a) do   print(i,v)end--上面的泛型for的写法可以改为下面的while写法do    local _it,_s,_k=ipairs(a)    while true do       k,v=_it(_s,_k)       _k=k       if k==nil then break end       print(k,v)    endend--输出结果--1 one--2 two--3 three --1 one--2 two--3 three 

 

3、无状态迭代器

 

function getnext(list,node)  if not node then return list  else return   node.next  endendfunction traverse(list)  return getnext,list,nilendlist=nilfor line in io.lines() do   list={next=list, value=http://www.mamicode.com/line}endfor node in traverse(list) do    print(node.value)end--输入--a--b--c--输出--c--b--a

 

通过上面的例子可以看出,可以无限次运用list变量和调用traverse函数而不必像第一种情况那样每次循环之前都创建新的closure变量。

 

Lua迭代器和泛型for