Lua中ipairs和pairs的区别

  • 泛型for
  • ipairs的实现
  • pairs的实现
  • 两者区别

泛型for

首先是泛型for的语法

for var-list in exp-list do body
end

当执行for循环时候,泛型for会接收exp-list返回的三个值分别用作迭代函数、不可变状态和控制变量的初始值。上述步骤完成后泛型for使用不可变状态和控制变量为参数来调用迭代函数,泛型for将迭代函数的返回值赋给变量列表中声明的变量,如果第一个返回值(赋给控制变量的值)为 nil ,那么循环终止;否则,泛型for执行它的循环体并再次调用迭代函数,再不断地重复这个过程。
伪代码是这样的:

local _f, _s, _var = exp-list
while true do local var_1, ... , var_n = _f(_s, _var)_var = var_1 if _var == nil then break end block
end

而ipairs和pairs是lua提供的两个迭代函数生成器也就是前面的exp-list

ipairs的实现

/*
** Traversal function for 'ipairs'
*/
static int ipairsaux (lua_State *L) {lua_Integer i = luaL_checkinteger(L, 2);// i = i + 1i = luaL_intop(+, i, 1);lua_pushinteger(L, i);// table[i] == nil and return 1 or return 2return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
}/*
** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
** (The given "table" may not be a table.)
*/
static int luaB_ipairs (lua_State *L) {luaL_checkany(L, 1);lua_pushcfunction(L, ipairsaux);  /* iteration function */lua_pushvalue(L, 1);  /* state */lua_pushinteger(L, 0);  /* initial value */return 3;
}

当我们使用ipairs的时候会调用luaB_ipairs,可以看到ipairs执行之后会返回三个参数,第一个参数是个遍历函数ipairsaux,第二个是ipairs函数调用时候传入的table,第三个参数是0。ipairs的遍历函数是通过 i 作为table的key,不断自增 i 从而达到遍历的效果的。

可以理解为如下代码:

local iter = function(t, i)i = i + 1local v = t[i]if v thenreturn i, vend
endfunction ipairs(t)return iter, t, 0
end

pairs的实现

static int luaB_next (lua_State *L) {luaL_checktype(L, 1, LUA_TTABLE);lua_settop(L, 2);  /* create a 2nd argument if there isn't one */if (lua_next(L, 1))return 2;else {lua_pushnil(L);return 1;}
}static int pairscont (lua_State *L, int status, lua_KContext k) {(void)L; (void)status; (void)k;  /* unused */return 3;
}static int luaB_pairs (lua_State *L) {luaL_checkany(L, 1);if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) {  /* no metamethod? */lua_pushcfunction(L, luaB_next);  /* will return generator, */lua_pushvalue(L, 1);  /* state, */lua_pushnil(L);  /* and initial value */}else {lua_pushvalue(L, 1);  /* argument 'self' to metamethod */lua_callk(L, 1, 3, 0, pairscont);  /* get 3 values from metamethod */}return 3;
}

当我们使用pairs的时候会调用luaB_pairs,在没有__pairs元方法的时候,可以看到pairs执行之后返回三个参数,第一个参数是个遍历函数luaB_next,第二个是pairs函数调用时候传入的table,第三个参数是nil。这里的luaB_pairs使用的就是遍历函数lua_next就是我们常用的next函数,也就是说pairs是通过不断调用next函数达到遍历的效果的。

可以理解为如下代码:

function pairs(t)return next, t, nil
end

两者区别

由他们的实现可以看出两者的区别
ipairs是没法保证完整遍历的,优势是可以有序遍历。
pairs是由于next的机制可以保证完整的遍历,但是却没办法保证顺序。

-- 遇table1[3]==nil时终止 ipairs可遍历到:a, b   pairs可遍历到:a, b, d
local table1 = { "a", "b", nil, "d" } -- ipairs可遍历到:a, b, d    pairs可遍历到:a, b, d
local table2 = { "a", "b", c = 1, "d" }

Lua中ipairs和pairs的区别相关推荐

  1. Lua中ipairs与pairs的区别

    Lua中ipairs与pairs的区别 首先我们要知道ipairs和pairs通常用在泛型迭代器与for联动使用. 如: for k, v in pairs(t) doprint(k, v) endf ...

  2. Lua中ipairs和pairs的区别详解

    迭代器for遍历table时,ipairs和pairs的区别: 区别一:ipairs遇到nil会停止,pairs会输出nil值然后继续下去 区别二: local a = {"Hello&qu ...

  3. Lua ipairs与pairs的区别

    Lua ipairs与pairs的区别 相同点和不同点 相同点 不同点: 举例说明 测试代码 测试结果分析 相同点和不同点 相同点 ipairs和pairs一般都用来对table进行遍历 不同点: i ...

  4. lua中table.和table[]的区别

    lua中table.和table[]的区别 lua中的table可以定义为如下格式 local tab = { ["one"] = 1, ["two"] = 2 ...

  5. ipairs与pairs的区别

    ipairs 和pairs在lua中都是遍历tbale的函数可是两者有差别 1.pairs遍历table中的全部的key-vale 而ipairs会依据key的数值从1開始加1递增遍历相应的table ...

  6. Lua中,泛型for循环遍历table时,ipairs和pairs的区别

    根据table型变量key是否为连续数字,如果是则称为数组型table,如果不是则称为非数组型table. 事实胜于雄辩,接下来通过实验来区分两组迭代器的区别. 首先给出pairs和ipairs在数组 ...

  7. 【Lua自学系列】Lua中ipair和pair的区别

    pairs会遍历table的所有键值对. 而ipairs就是固定地从key值1开始,下次key累加1进行遍历,如果key对应的value不存在,就停止遍历.顺便说下,记忆也很简单,带i的就是根据int ...

  8. Lua ipairs、pairs

      先给出 lua 官方 reference 中 ipairs 和 pairs 的解释: pairs (t) Returns three values: the next function, the ...

  9. Lua中 pairs 和 ipairs 的区别

    Lua中 pairs 和 ipairs 的区别 在我看来,pairs就是粗略计算,ipairs就是仔细计算. pairs只关注存在还是不存在,而ipairs还要关注存在是否合理. pairs将存在的值 ...

最新文章

  1. 2021年大数据Spark(十九):Spark Core的​​​​​​​共享变量
  2. windows hider
  3. BENDR for BCI : 多伦多大学研究者提出受BERT启发的深度神经网络学习​海量EEG 数据...
  4. QT数据库驱动和多国语言驱动部署注意事项
  5. JS排序算法之插入排序
  6. 计算机为何如此普遍英语论文,计算机英语论文
  7. 【转】C# 数据流详解(FileStream、MemoryStream、NetworkStream等类)
  8. python远程执行linux命令256_python远程操作Linux——使用paramiko库
  9. java bank项目答案_Bank项目-java
  10. mysql 5.7 enum_MYSQL中 ENUM 类型的详细解释
  11. DDD~microsoft NLayerApp项目中的层次结构图
  12. 一文2000字搞懂高并发性能指标:QPS、TPS、RT、并发数、吞吐量
  13. 小故事折射出大道理:风靡办公室的管理寓言
  14. Ant Design Pro 从零到一教程
  15. html 列表页 后台添加分类 后台添加商品 商品详情页 注册页面 首页
  16. 怎样将pdf压缩得很小?如何把pdf压缩到最小?怎么把pdf压缩到最小?如何把pdf文档压缩变小?怎么将pdf文档压缩至更小?怎么把pdf压缩到最小方法软件网站有哪些?
  17. python3 安装PIL模块
  18. 【Android】Android 集成商米内置打印机打印票据
  19. 宏观经济调控政策笔记+
  20. 矢量科研数据质量检查方法

热门文章

  1. AndroidQ与腾讯tbs的兼容问题
  2. 80c51汇编语言程序案例指导,新第4章80C51的汇编语言程序设计
  3. Java闭关修炼64课 很适合新手学习的JAVA视频教程
  4. 数据库基础考点笔记-3
  5. CentOS7.5搭建Heartbeat+DRBD+NFS高可用共享存储
  6. Disabling usage of PDSC Debug Description
  7. 2011年最值得阅读的财富故事,蒋百荣论商经小赢在智大赢在德
  8. 用javascript预加载图片、css、js的方法研究
  9. 爬虫六、gevent协程与queue模块
  10. python 响铃_python响铃符不响_python语法注意事项