Lua迭代器

在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素.迭代器需要保留上一次成功调用的状态和下一次成功调用的状态,可以通过闭包提供的机制来实现这个任务(闭包中的外部局部变量可以用来保存状态)。一个典型的闭包结构包含两个函数:一个是闭包自己,另一个是工厂(创建闭包的函数).

function list_iter(t)
    local i=0
    local n=table.getn(t)
    return function()
        i=i+1
        if i<=n then return t[i] end
    end
end

t={10,20,30}
for elem in list_iter(t) do
    print(elem)
end
--返回的是函数
function iterator(t)
    local i=0
    local n=table.getn(t)
    return function()
        i=i+1
        if i<=n then
            return t[i]
        end
    end
end

t={10,20,30}

iter=iterator(t)--获取迭代器
while true do
    local e=iter()
    if e==nil then break end
    print(e)
end

 

范性for的语义:

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

无状态的迭代器:不保留任何状态的迭代器,避免创建闭包花费额外的代价.

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

a={"one","two","three"}
--调用_ipairs(a)开始循环时,获取三个值:迭代函数、状态常量a,控制变量初始值0
for i,v in _ipairs(a) do
    print(i,v)
end

应该尽可能的写无状态的迭代器,这样循环的时候由for来保存状态;如果不能用无状态的迭代器实现,应尽可能使用闭包,尽可能不要使用table这种方式,因为创建闭包的代价要比创建table小,另外lua处理闭包要比处理table速度快些。

local iterator

function allwords()
    local state={line=io.read(),pos=1}--使用table保存状态常量、控制变量
    return iterator,state
end

function iterator(state)
    while state.line do
        local s,e=string.find(state.line,"%w+",state.pos)
        if s then
            state.pos=e+1
            return string.sub(state.line,s,e)
        else
            state.line=io.read()
            state.pos=1
        end
        return nil
    end
end

 

posted @ 2015-04-28 11:47  合唱团abc  阅读(281)  评论(0编辑  收藏  举报