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

在 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

点赞
用户3204551
用户3204551

在 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 和起始点 nilnext 接受一个表和一个索引,如果存在,则返回下一个索引和关联的值。

    因此,它将以某种随意的顺序显示所有元素。

  3. 函数有无限的创造力,这是纯 Lua 的期望。

    请参见 "Lua 中的 Bizzare“尝试调用表值”",其中有一个用户编写的可调用的示例,以及某些方言如果第一个值实际上不是可调用的情况下如何反应。

2019-03-11 19:47:40
用户10808674
用户10808674

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因为它不是数字键; -10,因为尽管它们是数字,但它们的值小于1,以及; 6,因为我们隐式有u[5] = nil,在迭代时找到nil值恰好是ipairs()的结束条件。

最后,注意,就像在您的示例中一样,当您创建一个未指定任何键的表时,例如 a = {“one”,“two”,“three”},会将从1开始的数字键隐式分配给每个值,即定义被理解为 a = { [1] = "one", [2] = "two", [3] = "three" }。因此,在这些情况下使用pairs()ipairs()基本相同,除了pairs()不保证排序。

2019-03-11 19:55:16