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

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

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

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

输出如下:

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 <= 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所创建的协同程序的状态,此外,也无法检测出运行时的错误。

《Lua程序设计》9.3 以协同程序实现迭代器 学习笔记的更多相关文章

  1. 《Lua程序设计》9.1 协同程序基础 学习笔记

    协同程序(coroutine)与线程(thread)差不多,也就是一条执行序列,拥有自己独立的栈.局部变量和指令指针,同时又与其他协同程序共享全局变量和其他大部分东西.从概念上讲线程与协同程序的主要区 ...

  2. 《Lua程序设计》第2章 类型与值 学习笔记

    Lua中的8中基础类型:nil(空).boolean(布尔).number(数字).string(字符串).userdata(自定义类型).function(函数).thread(线程)和table( ...

  3. chapter9_3 协同程序实现迭代器

    将循环迭代器视为"生产者-消费者"模式的一种特例:迭代器产生的数据供循环体消费. 因此,用协同程序写迭代器就理所当然了.因为协同程序可以一改传统调用者与被调用者之间的关系. 有了这 ...

  4. 微信小程序开发:学习笔记[5]——JavaScript脚本

    微信小程序开发:学习笔记[5]——JavaScript脚本 快速开始 介绍 小程序的主要开发语言是 JavaScript ,开发者使用 JavaScript 来开发业务逻辑以及调用小程序的 API 来 ...

  5. 微信小程序开发:学习笔记[7]——理解小程序的宿主环境

    微信小程序开发:学习笔记[7]——理解小程序的宿主环境 渲染层与逻辑层 小程序的运行环境分成渲染层和逻辑层. 程序构造器

  6. 微信小程序开发:学习笔记[4]——样式布局

    微信小程序开发:学习笔记[4]——样式布局 Flex布局 新的布局方式 在小程序开发中,我们需要考虑各种尺寸终端设备上的适配.在传统网页开发,我们用的是盒模型,通过display:inline | b ...

  7. 微信小程序开发:学习笔记[3]——WXSS样式

    微信小程序开发:学习笔记[3]——WXSS样式 快速开始 介绍 WXSS(WeiXin Style Sheets)是一套用于小程序的样式语言,用于描述WXML的组件样式,也就是视觉上的效果. WXSS ...

  8. 微信小程序开发:学习笔记[2]——WXML模板

    微信小程序开发:学习笔记[2]——WXML模板 快速开始 介绍 WXML 全称是 WeiXin Markup Language,是小程序框架设计的一套标签语言,结合小程序的基础组件.事件系统,可以构建 ...

  9. 微信小程序开发:学习笔记[1]——Hello World

    微信小程序开发:学习笔记[1]——Hello World 快速开始 1.前往微信公众平台下载微信开发者工具. 地址:https://mp.weixin.qq.com/debug/wxadoc/dev/ ...

随机推荐

  1. 【转载】Exchange 2010配置与安装实用手册

    Exchange 2010配置与安装实用手册 在Exchange 2010配置的时候主要分三大部分,这分别是网络配置.准备存储以及相关的安装策略和过程.同时还需要注意和其他的Windows软件相协调. ...

  2. 容易出错的 if 语句

    下面列举几个容易出错的if语句实例,如果后续还有新的发现,还会继续更新! 出错一:在括起控制表达式的括号后面加分号 ; ); printf("值为正"); 初次运行,感觉一切正常, ...

  3. e770. 确定按钮租中已选的单选按钮

    When you ask a button group for the currently selected radio button, it returns the selected radio b ...

  4. 使用ConcurrentLinkedQueue惨痛的教训【转】

    转自:http://blog.csdn.net/jackpk/article/details/49634577 服务端原本有个定时任务对一个集合ArrayList 中的消息做处理. 因为考虑到处理消息 ...

  5. 机器学习——使用Apriori算法进行关联分析

    从大规模的数据集中寻找隐含关系被称作为关联分析(association analysis)或者关联规则学习(association rule learning). Apriori算法 优点:易编码实现 ...

  6. Thinkphp5笔记九:路由设置,隐藏indx.php

    网站根目录下.htaccess <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine on ...

  7. 【WP8】自定义配置存储类

    之前在WP7升级到WP8的时候遇到配置不兼容的问题 情景:之前只有一个WP7版本,现在需要发布WP8版本,让用户可以从原来的WP7版本升级到WP8版本 一般情况下从WP7升级到WP8没什么问题 但是在 ...

  8. Npm基本指令(转)

    一些常用的 npm 指令 當你設定好 node.js 的開發環境後, 是時候來把下面這些常用的 npm 指令給摸熟了. 將套件於全域安裝. 全域安裝的套件通常只是為了執行檔而已. $ npm inst ...

  9. perforce使用技巧

    如果用其他编辑器打开一个在perforce上的文件, 只需要在notepad++ (或者其他)上右键选择 然后到perforce的workspace里Ctrl + V 即可定位到该文件. 再使用Ctr ...

  10. multiselect2side:jQuery多选列表框插件

    http://blog.csdn.net/rosanu_blog/article/details/8550723 http://www.bkjia.com/jQuery/449193.html < ...