Lua中pairs()和ipairs()的区别是啥?

Posted

技术标签:

【中文标题】Lua中pairs()和ipairs()的区别是啥?【英文标题】:What is the difference of pairs() vs. ipairs() in Lua?Lua中pairs()和ipairs()的区别是什么? 【发布时间】:2019-08-02 04:14:17 【问题描述】:

在for循环中,使用pairs()和ipairs()循环有什么区别?此页面同时使用:Lua Docs

使用 ipairs():

a = "one", "two", "three"
for i, v in ipairs(a) do
  print(i, v)
end

结果:

1   one
2   two
3   three

使用pairs():

a = "one", "two", "three"
for i, v in pairs(a) do
  print(i, v)
end

结果:

1   one
2   two
3   three

你可以在这里测试它:Lua Demo

【问题讨论】:

【参考方案1】:

pairs()ipairs() 略有不同。

pairs() 返回键值对,主要用于关联表。密钥顺序未指定。 ipairs() 返回索引值对,主要用于数值表。数组中的非数字键被忽略,而索引顺序是确定性的(按数字顺序)。

下面的代码片段说明了这一点。

> u=
> u[1]="a"
> u[3]="b"
> u[2]="c"
> u[4]="d"
> u["hello"]="world"
> for key,value in ipairs(u) do print(key,value) end
1   a
2   c
3   b
4   d
> for key,value in pairs(u) do print(key,value) end
1   a
hello   world
3   b
2   c
4   d
> 

当您创建没有键的表时(如您的问题所示),它的行为类似于数字数组,行为或对和 ipairs 是相同的。

a = "one", "two", "three"

相当于a[1]="one"a[2]="two"a[3]="three"pairs()ipairs() 将是相同的(除了在pairs() 中不保证的顺序)。

【讨论】:

我相信pairs()可以保证排序,它会通过数字索引,然后会以随机顺序进入其他非数字值。 @BeastCoder2:在lua.org/manual/5.3/manual.html#pdf-next,它表示“未指定枚举索引的顺序,即使是数字索引。”您所描述的可能是 Lua 中的常见行为,但它可能会在任何错误修复版本中发生变化。 @luther 谢谢你的澄清!它可能只是我用来运行代码的东西。 我还看到 pairs 按顺序迭代从 1 开始的连续整数索引(有时是非连续整数索引),但不能保证。 关于ipairs 的另一个重要点是它只循环索引的第一个序列,从1 开始:它在第一个间隙处停止。考虑for i,v in ipairs([1]='a', [2]='b', [4]='d') do print(i,v) endfor i,v in ipairs([2]='a', [3]='b', [4]='d') do print(i,v) end【参考方案2】:

Lua 中没有 array-type,只有 tables 可能有从索引 1 开始的连续元素。

与数字 for 循环相比,通用 for 循环需要三个值:

    一个可调用对象 它传递的上下文值 初始索引值

它使用上下文值和索引值调用可调用对象,将所有返回值存储在提供的新变量中。第一个额外保存为新的索引值。

现在循环调用的一些代表性示例:

    ipairs(t) 返回一个函数,表格t,起点0。 该功能在道德上等同于:

    function ipairs_next(t, i)
        i = i + 1
        var v = t[i]
        if v ~= nil then
            return i, v
        end
    end
    

    因此,会显示从 1 开始直到第一个缺失的所有数字条目。

    pairs(t) 或者委托给t 的元表,特别是__pairs(t),或者返回函数next、表t 和起点nilnext 接受表和索引,如果存在,则返回下一个索引和关联值。

    因此,所有元素都以任意顺序显示。

    这个功能的创意是没有限制的,这正是原版 Lua 所期望的。 请参阅“Bizzare "attempt to call a table value" in Lua”了解用户编写的可调用对象的示例,以及如果第一个值实际上不是可调用对象,某些方言会如何反应。

【讨论】:

我是这门语言的新手,想知道每个是什么,每种类型的 for 循环是什么?什么是可调用的、上下文值和索引值? ipairs_next 是什么,你做的一个函数? 我也是 lua 新手,但我认为它是一个迭代器函数,查找“编程中的迭代器”

以上是关于Lua中pairs()和ipairs()的区别是啥?的主要内容,如果未能解决你的问题,请参考以下文章

lua 中pairs 和 ipairs区别

Lua中ipairs和pairs的区别详解

lua中pairs和ipairs的区别

lua pairs和ipairs的区别

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

LUA入门以及ipairs pairs的区别