范性for语义以及pair和ipair的区别
详情参考 lua手册
1. 范性for语义
在了解pair和ipair前先简单了解下lua中的for循环,这里只阐述范性for循环的语义,范性 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。for的范式如下
for <var-list> in <exp-list> do
<body>
end
<var-list>是以一个或多个逗号分隔的变量名列表,<exp-list>是以一个或多个逗号分隔的表达式列表,通常情况下 exp-list 只有一个值:迭代函数的调用。
for k, v in pairs(t) do
print(k, v)
end
首先,初始化,计算 in 后面表达式的值,表达式应该返回范性 for 需要的三个值:迭代函数、状态常量、控制变量;与多值赋值一样,如果表达式返回的结果个数不足三个会自动用 nil 补足,多出部分会被忽略。
第二,将状态常量和控制变量作为参数调用迭代函数(注意:对于 for 结构来说,状态常量没有用处,仅仅在初始化时获取他的值并传递给迭代函数)。
第三,将迭代函数返回的值赋给变量列表。
第四,如果返回的第一个值为 nil 循环结束,否则执行循环体。
第五,回到第二步再次调用迭代函数。
2. ipair函数
无状态的迭代器是指不保留任何状态的迭代器,因此在循环中我们可以利用无状态迭代器避免创建闭包花费额外的代价。每一次迭代,迭代函数都是用两个变量(状态常量和控制变量)的值作为参数被调用,一个无状态的迭代器只利用这两个值可以获取下一个元素。这种无状态迭代器的典型的简单的例子是 ipairs,他遍历数组的每一个元素。
a = {"one", "two", "three"}
for i, v in ipairs(a) do
print(i, v)
end function iter (a, i)
i = i +
local v = a[i]
if v then
return i, v
end
end function ipairs (a)
return iter, a,
end
在上面的代码中,ipairs函数返回三个值,迭代函数为iter,a为状态常量,控制变量的初始值为0,这三者由for语义保存,每次调用迭代函数iter返回表中的key和value,即 i 和 v 的值,可以看到,在pair中,只能遍历有数字索引的元素。如果出现如下图的情况,会无法遍历所有数字索引元素。
3. pair函数
ipair函数主要由lua的内置函数next实现,next原型大致为 next (table [, index])。它允许程序遍历表的所有字段。它的第一个参数是一个表,它的第二个参数是该表中的索引。 next返回表的下一个索引及其关联值。当使用nil作为其第二个参数调用时, next返回初始索引及其关联值。使用最后一个索引调用时,或者在空表中使用nil时, next返回nil。如果第二个参数不存在,则将其解释为nil。此外你可以使用next(t)检查表是否为空。pair有两种形式,如下。
function pairs (t)
return next, t, nil
end for k, v in next, t do
...
end
4. 总结
- 范性for语义是将for循环中 in 后面的表达式进行求值,获取到状态常量,迭代函数以及控制变量,然后将状态常量和控制变量传入迭代函数中求的key和value的值返回给for循环中的变量列表,直到第一个变量为nil时停止循环。其中状态常量通常指表,控制变量即遍历的步长。
- pair可以遍历一个table的所有元素,而ipair只能遍历数字索引的元素,此外,如果索引不是连续的ipair会无法遍历所有索引
- pair是由next函数实现的,next函数可以用来判断一个表是否为空, 即判断 next(t) == nil
范性for语义以及pair和ipair的区别的更多相关文章
- Lua table pair和ipair区别
官方描述: ipairs (t) Returns three values: an iterator function, the table t, and 0, so that the constru ...
- HTML5中最看重的理念“语义化”相比HTML有什么区别?
这里搜集整理了一些语义化标签方面的问题和解答,以供大家参考. 语义化这个概念应该说是伴着HTML5应运而生,那么什么是HTML5中所谓的语义化? 简单来说就是:描述内容的含义(meaning) 比如说 ...
- 语义化标签SEO
语义标签 title 和 h1 的区别,我的理解是: title 是整个网页的标题,突出整个网站的内容,H1 突出的是一篇文章的内容. b 与 strong 的区别,b只是样式的加粗,strong 是 ...
- Java并发编程原理与实战四十二:锁与volatile的内存语义
锁与volatile的内存语义 1.锁的内存语义 2.volatile内存语义 3.synchronized内存语义 4.Lock与synchronized的区别 5.ReentrantLock源码实 ...
- C++ pair的基本用法总结
1,pair的应用 pair是将2个数据组合成一组数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存.另一个应用是,当一个函数需要返回2个数据的时候, ...
- Lua知识备忘录
最近对Lua很感兴趣,以下是本阶段学习的总结,包含三部分,一部分是基础语法,一部分是扩展和解释器嵌入,最后一部分是Lua小练习. 知识涉及:Lua语言编程基础:Lua&C++:Lua扩展.嵌入 ...
- 十一、C# 泛型
为了促进代码重用,尤其是算法的重用,C#支持一个名为泛型的特性. 泛型与模块类相似. 泛型使算法和模式只需要实现一交.而不必为每个类型都实现一次.在实例化的时候,传入相应的数据类型便可. 注:可空值类 ...
- C#泛型的抗变与协变
C#泛型的抗变与协变 学习自 C#本质论6.0 https://www.cnblogs.com/pugang/archive/2011/11/09/2242380.html Overview 一直以来 ...
- cs108 03 ( 调试, java通用性)
Debuger Great questions These questions will solve most bugs: what method shows the symptom ? what l ...
随机推荐
- .Net移动开发平台 ,基于VisualStudio的可视化开发——Smobiler平台入门教程
通过以下步骤,可以简单了解到如何下载Smobiler Designer(设计器).Client(客户端),以及如何通过设计器进行开发和调试移动应用,并在服务端部署.Cloud打包.访问您所开发的移动应 ...
- sql 脚本编写之路 常用语句(一) 1.用一个表中的某一列更新另外一个表的某些列:
for ACCESS 数据库: update a, b set a.name=b.name1 where a.id=b.id for SQL Server 数据库: update a set a.na ...
- [转]Uipath、BluePrism、AA产品对比之设计器篇
本文转自:https://www.jianshu.com/p/53d0d33a1a35 版本说明: Uipath V2018.3.2,BluePrism V6.3,Automation Anywher ...
- 简述ADO中如何使用参数化的命令对象以及增删改查,存储过程的操作
连接数据库代码: private SqlConnection con = null; public void OpenConnection(string connectionString) { con ...
- Php7.3 could not find driver
今天phpstudy升级php7.3,发现框架报错:could not find driver,后来发现默认php.ini的配置有几个是注释掉的,配置php.ini,修改如下 extension=my ...
- Java 工厂模式(一)— 抽象工厂(Abstract Factory)模式
一.抽象工厂模式介绍: 1.什么是抽象工厂模式: 抽象工厂模式是所有形态的工厂模式中最为抽象和最具有一般性的一种形态,抽象工厂模式向客户端提供一个接口,使得客户端在不知道具体产品的情类型的情况下,创建 ...
- hive基本操作与应用
通过hadoop上的hive完成WordCount 启动hadoop Hdfs上创建文件夹 上传文件至hdfs 启动Hive 创建原始文档表 导入文件内容到表docs并查看 用HQL进行词频统计,结果 ...
- QQ音乐vkey获取,更新播放url
QQ音乐接口播放经常换, 最开始 url: `http://ws.stream.qqmusic.qq.com/${musicData.songid}.m4a?fromtag=46` 然后 url:`h ...
- Spring Boot 入门(五):集成 AOP 进行日志管理
本篇文章是接着 Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理写的,按照前面几篇博客的教程,可以搭建一个简单的项目,主要包含了 Pagehelper+MyBatis 分页 ...
- 服务器三:多线程epoll
#include <fcntl.h> #include <sys/socket.h> #include <netinet/in.h> #include <ar ...