Lua中pairs()和ipairs()有什么区别?

问题描述 投票:0回答:2

for
循环中,使用
pairs()
ipairs()
循环有什么区别?

《Lua 编程》book 提到了两者,但是,两者似乎都生成类似的输出,如下所示:

使用

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
for-loop lua
2个回答
189
投票

ipairs()
pairs()
略有不同,如您在 手册参考 中所见。 技术性较低的描述可能是:

  • ipairs()
    返回索引值对,主要用于数字表。 非数字键将被整体忽略,类似于小于 1 的数字索引。 此外,指数之间的差距也会导致停牌。 排序是确定的,按数值大小排列。

  • pairs()
    返回键值对,主要用于关联表。 所有密钥均被保留,但顺序未指定。

此外,虽然

pairs()
可用于获取表的大小(请参阅另一个问题),但使用
ipairs()
来执行同一任务是不安全的,因为它可能会丢失一些键。

以下代码片段说明了两个选项之间的差异。

> u = {}
> u[-1] = "y"
> u[0] = "z"
> u[1] = "a"
> u[3] = "b"
> u[2] = "c"
> u[4] = "d"
> u[6] = "e"
> 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
2       c
3       b
4       d
6       e
0       z
hello   world
-1      y
> 

正如我们在示例中看到的,虽然

pairs()
的所有键都出现在输出中,但
ipairs()
缺少一些键:
hello
因为它不是数字键;
-1
0
,因为尽管它们是数字,但它们的值小于 1,并且;
6
假设我们隐含地拥有
u[5] = nil
,并且在迭代时找到 nil 值正是
ipairs()
的结束条件。

最后,请注意,如您的示例中所示,当您创建表而不指定任何键(例如

a = {"one", "two", "three"}
)时,从 1 开始的数字键将隐式分配给每个值,即定义被理解为
a = { [1] = "one", [2] = "two", [3] = "three" } 
。 因此,在这些场景中使用
pairs()
ipairs()
基本上是相同的,除了
pairs()
的非保证顺序之外。


4
投票

Lua 中没有

array
类型,只有
table
可能具有从索引 1 开始的连续元素。实现甚至针对该用途进行了优化。

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

  1. 可调用
  2. 它传递的上下文值
  3. 初始索引值

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

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

  1. 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 开始直到第一个缺失的所有数字条目。

  2. pairs(t)
    要么委托给
    t
    的元表,特别是
    __pairs(t)
    ,要么返回函数
    next
    、表
    t
    和起点
    nil

    next
    接受一个表和一个索引,并返回下一个索引和关联值(如果存在)。

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

  3. 人们对函数的创造性是没有限制的,这正是 vanilla Lua 所期望的。
    请参阅“*https://stackoverflow.com/questions/23350281/bizzare-attempt-to-call-a-table-value-in-lua*”,了解用户编写的可调用对象的示例,以及某些方言如何如果第一个值实际上不是可调用的,则做出反应。

© www.soinside.com 2019 - 2024. All rights reserved.