Lua 迭代器与closure_weixin_30950237的博客-程序员宅基地

技术标签: lua  

所谓“迭代器”就是一种可以遍历(iterate over)一种极和中所有元素的机制。在Lua中,通常将迭代其表示为函数。每调用一次函数,即返回集合中的“下一个”元素。
每个迭代器都需要在每次成功调用之间保持一种状态,这样才能知道它所在的位置及如何步进到下一个位置。closure对于这类人无提供了极佳的支持,一个closure就是一种可以访问外部嵌套环境中的局部变量的函数。对于closure而言,这些变量就可用于在成功调用之间保持状态值,从而使closure可以记住它在一次遍历中所在的位置。当然,为了创建一个新的closure,还必须创建它的这些“非局部的变量(non-local variable)”。因此一个closure结构通常涉及到两个函数:closure本身和一个用于创建该closure的工厂(factory)函数。
作为示例,来为列表写一个简单的迭代器。与ipairs不同的是该迭代式并不是返回每个元素的索引,而是返回元素的值(返回什么还不是由自己决定嘛):

function values (t)
    local i = 0
    return function () i = i + 1; return t[i] end
end

在本例中,values就是一个工厂。每当调用这个工厂时,它就创建一个新的closure(即迭代器本身)。这个closure将它的状态保存在其外部变量t和i中。每当调用这个迭代器时,它就从列表t中返回下一个值。知道最后一个元素返回后,迭代其就会返回nil,一次表示迭代的结束。
可以在一个while循环中使用这个迭代器:

t = {
    10, 20, 30}
iter = values(t)                -- 创建迭代器
while true do
    local element = iter()      -- 调用迭代器
    if element == nil then break end
    print(element)
end

然而使用泛型for则更为简单。接下来会发现,它真实为这种迭代而设计的:

t2 = {
    40, 50, 60}
for element in values(t2) do
    print(element)
end

泛型for为一次迭代循环做了所有的蒲记工作。它在内部保存了迭代器函数,因此不再需要iter变量。它在每次新迭代时调用迭代器,并在迭代器返回nil时结束循环。

[迭代器示例——遍历文件中所有单词]
下面的示例中展示了一个可以遍历当前输入文件中所有单词的迭代器——allwords。为了完成这样的遍历,需要保持两个值:当前行的内容(变量line)及在该行中所处的位置(变量pos)。
这里用到一个string.find函数,返回当前查找单词位置。
尽管迭代器本身具有复杂性,但allwords的使用还是很简明易懂的:

for word in allwords() do
    print(word)
end

对于迭代器而言,一种常见的情况就是:编写迭代器本身或许不太容易,但使用它们却是很容易的。这也不会称为一个大问题,因为通常使用Lua编成的最终用户不会去定义迭代器,而只是使用那些程序提供的迭代器。

function allwords ()
    local line = io.read()      -- 当前行
    local pos = 1               -- 一行中的当前位置
    return function()           -- 迭代器函数
        while line do           -- 若为有效的行内容就进入循环
            local s, e = string.find(line, "%w+", pos)
            if s then           -- 是否找到一个单词
                pos = e + 1     -- 该单词的下一个位置
                return string.sub(line, s, e)   -- 返回该单词
            else
                line = io.read()    -- 没有找到单词,返回下一行
                pos = 1             -- 在第一个位置重新开始
            end
        end
        return nil              -- 没有其余行了,遍历结束
    end
end

 

转载于:https://www.cnblogs.com/moonlightpoet/p/5685275.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30950237/article/details/96708200

智能推荐

最好用的 Eclipse 插件_eclipse 单词拼写错误检测插件_HEHE的博客-程序员宅基地

1、ExploreFS 此插件的功能是在项目管理器的右键菜单中增加一项 “Open in File System”,可以通过该项打开选中的资源所在的文件系统目录。 安装地址:http://www.junginger.biz/eclipse/2、JSON 编辑插件  用于编辑 JSON 字符,具有语法校验、高亮显示、以及格式化文本的功能。官网上有使用截图,_eclipse 单词拼写错误检测插件

android程序员面试问什么问题,Android程序员必备的十大面试问题_weixin_29062865的博客-程序员宅基地

废话不多说,作为一名Android开发者,挑战高薪必备的十大面试题,看看自己能到第几题?一、Android中五种数据存储方式分别是什么?他们的特点?Android提供了五种存取数据的方式1)SharedPreference,存放较少的五种类型的数据,只能在同一个包内使用,生成XML的格式存放在设备中;2)SQLite数据库,存放各种数据,是一个轻量级的嵌入式数据库;3)File文件,通过读取写入方..._面试安卓开发问什么

AndroidStudio解决unspecifiedonprojectappresolvestoanAPKarchivewhichisnotsupported_香隅人的博客-程序员宅基地

出现该问题unspecified on project app resolves to an APK archive which is not supported as a compilation dependency的情形可能是:创建了两个Module,其中一个Module依赖另一个Module而导致了出现该问题; 如果在Android Studio中,有ModuleA和

Jupyter notebook kernel error 无法使用:pywintypes.error: (87, ‘SetFileSecurity‘, ‘参数错误.‘)_pywintypes.error: (87, 'openprocess', '参数错误。')_there2belief的博客-程序员宅基地

问题:启动jupyter notebook正常打开,但kelnel error无法正常使用,提示错误:pywintypes.error: (87, 'SetFileSecurity', '参数错误.') 或 pywintypes.error: (87, 'SetFileSecurity', 'Parameters incorrect.')。解决方案:Win Error大都是系统环境问题导致的。SetFileSecurity看着是需要一些写操作权限的,jupyter notebook需要C:._pywintypes.error: (87, 'openprocess', '参数错误。')

Java操作word模板插入图片_xwpftemplate 插入图片_哥德施密特的博客-程序员宅基地

1.使用Poi-tl,添加依赖<dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.0.0</version></dependency>po_xwpftemplate 插入图片

python文件处理_for maindir, subdir, file_name_list in os.walk(exc_云_磊的博客-程序员宅基地

python过滤文件中错误行的内容-- conding: UTF-8 --master=input(“请输入你要处理的数据的名字:”) fh = open(master+”.TextGrid”) #打开输入的文件名不包含后缀 for line in fh.readlines(): #读取文件每行内容 newStr = line.strip() ..._for maindir, subdir, file_name_list in os.walk(excelpath):

随便推点

GAMES101-现代计算机图形学入门-闫令琪——Lecture 13 Ray Tracing 1_逩跑の油條的博客-程序员宅基地

GAMES101-现代计算机图形学入门-闫令琪——Lecture 13 Ray Tracing 1目录GAMES101-现代计算机图形学入门-闫令琪——Lecture 13 Ray Tracing 1Why Ray Tracing?Basic Ray-Tracing AlgorithmLight RaysRay Casting - Shading Pixels (Local Only)光线投射法Recursive (Whitted-Style) Ray Tracing(Whitted风格的光线追踪)Ray

利用jmeter向mysql数据库中插入数据_使用jmeter新增mysql数据_祖传叮当手的博客-程序员宅基地

准备工作:1.已安装好的jmeter2.mysql-connector-java.jar包:https://download.csdn.net/download/qq_41919825/103155693.mysql数据库4.数据库名称test,表名称tmptable,字段id(int)自增主键,username(varchar),age(int)。第一步:打开jmeter,添加测试计划,编辑测试..._使用jmeter新增mysql数据

Microsoft Dynamics CRM 2013 新功能 团队 ,访问团队_weixin_33739523的博客-程序员宅基地

在Dynamics CRM 中有团队(Team)的概念。可以跨部门跨组织将多人组成一个团队,进行通力合作,这种团队和用户一样,可以拥有纪录,也就是作为纪录的负责人。访问团队(Access Team)是Dynamics CRM 2013新引入的东东,是一种轻量级别的团队。它不能拥有纪录,但是能访问纪录,当然不限于访问,包括更新,删除,共享等权限。你也可以将不同的人加..._dynamic crm 团队有哪2种团

python boxplot 画盒须图_boxplot(by=)-程序员宅基地

python 用boxplot 绘制盒须图import osimport matplotlib.pyplot as pltimport pandas as pdimport matplotlibos.chdir(r"D:\python金融")data = pd.read_csv("house_price.csv")matplotlib.rcParams['axes.unicode..._boxplot(by=)

阿里云服务器配置CentOS7.4+Open***-2.4.5+easy-rsa-3.0_weixin_33882452的博客-程序员宅基地

一、安装open***#yum install open***#yum install easy-rsa二、生成证书1、准备:# cp /usr/share/doc/open***-2.4.5/sample/sample-config-files/server.conf /etc/open***# cp -r /usr/share/easy-rsa/ /etc/open***# cp /u..._阿里云服务ta.key

python 3以上版本cv2.imread读取中文路径下的图像为NONE_cv2.imread哪个版本有_烂柯人8的博客-程序员宅基地

使用的程序中使用到了cv2.imread(),程序各种bug,将读取结果打印出来发现是None,然后主要找到了两种解决方法#先介绍复杂一点的——暗度陈仓可以使用MATLAB先读取图片生成.mat文件,再使用Python读取.mat文件传入数据。在这里要注意数据形式的改变,cv2.imread()读取出来为ndarray形式,而读取.mat文件后的数据为dict形式,所以需要进行格式转换。#另..._cv2.imread哪个版本有

推荐文章

热门文章

相关标签