• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

《Lua程序设计》9.3以协同程序实现迭代器学习笔记

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

例:编写一个迭代器,使其可以遍历某个数组的所有排列组合形式。代码如下:

function permgen(a, n)
    n = n or #a         -- 默认n为a的大小
    if n <= 1 then      -- 还需要改变吗?
        printResult(a)
    else
        for i=1,n do
            -- 将第一个元素放到数组末尾
            a[n], a[i] = a[i], a[n]
            -- 生成其余元素的排列
            permgen(a, n-1)
            -- 恢复第i个元素
            a[n], a[i] = a[i], a[n]
        end
    end
end

然后,还需要定义其中调用到的打印函数printResult,并以适当的参数来调用permgen:

function printResult (a)
    for i=1,#a do
        io.write(a[i], " ")
    end
    io.write("\n")
end

permgen ({1,2,3,4})

输出如下:

2 3 4 1 
3 2 4 1 
3 4 2 1 
4 3 2 1 
2 4 3 1 
4 2 3 1 
4 3 1 2 
3 4 1 2 
3 1 4 2 
1 3 4 2 
4 1 3 2 
1 4 3 2 
2 4 1 3 
4 2 1 3 
4 1 2 3 
1 4 2 3 
2 1 4 3 
1 2 4 3 
2 3 1 4 
3 2 1 4 
3 1 2 4 
1 3 2 4 
2 1 3 4 
1 2 3 4 

当生成函数完成后,将其转换为一个迭代器就非常容易了。首先,将printResult改为yield:

function permgen (a, n)
    n - n or #a
    if n <= 1 then
        coroutine.yield(a)
    else
        <as before>

然后,定义一个工厂方法,用于将生成函数放到一个协同程序中运行,并创建迭代器函数。迭代器指示简单地唤醒协同程序,让其产生下一种排列:

function permutations (a)
    local co = coroutine.create(function () permgen(a) end)
    return function ()  -- 迭代器
        local code, res = coroutine.resume(co)
        return res
    end
end

有了上面的函数,在for语句中遍历一个数组中的所有排列就非常简单了:

for p in permutations {"a", "b", "c"} do
    printResult(p)
end
--> b c a
--> c b a
--> c a b
--> b a c
--> a b c

permutations函数使用了一种在Lua中比较常见的模式,就是将一条唤醒协同程序的调用包装在一个函数中。由于这种模式比较常见,所以Lua专门提供了一个函数coroutine.wrap来完成这个功能。类似于create,wrap创建了一个新的协同程序。但不同的是,wrap并不是返回协同程序本身,而是返回一个函数。每当调用这个函数,即可唤醒一次协同程序。但这个函数与resume的不同之处在于,它不会返回错误代码。当遇到错误时,它会引发错误。若使用wrap,可以这么写permutations:

function permutations (a)
    return coroutine.wrap(function () permgen(a) end)
end

通常,coroutine.wrap比couroutine.create更易于使用。它提供了一个对于协同程序编程实际所需的功能,即一个可以唤醒协同程序的函数。但也缺乏灵活性。无法检查wrap所创建的协同程序的状态,此外,也无法检测出运行时的错误。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap