`table.pack` 添加到表中的 `n` 字段的用途?哎呀,为什么 `table.pack` 甚至存在?

Purpose of `n` field added to tables by `table.pack`? Heck, why does `table.pack` even exist?

标题说明了一切。我想知道为什么 Lua 在使用 table.pack() 时向 table 添加一个 n 字段。

从字面上看,您可以这样实现:

function pack(...)
    return { n = select("#", ...), ... }
end

-- pretty useless

我看不出有什么意义,因为您可以使用 {} 构造一个 table 并使用 #tbl 来获取 table 中有多少个元素。

local tbl = table.pack('a', 'b', 'c', 'd')
print(tbl.n, #{ 'a', 'b', 'c', 'd' }) -- 4    4

-- Same thing

如果你用next去遍历一个用table.pack构造的table,那真的会毁掉迭代。 Ofc 你可以使用 ipairs 但对于那些不使用的人呢?哦,长度运算符不会计算 n.

table.pack() 不需要 return 序列。只有当所有参数都是非 nil.

时才会这样做

因此,如果要反转它,一般情况下需要 "n"-成员。

table.unpack(t, 1, t.n)

尽管实现非常简单,table.pack() 仍然是一个有用的抽象。

local tbl = table.pack('a', 'b', nil, 'd', nil)
print(tbl.n, #{ 'a', 'b', 'c', 'd' }) -- 5    2

-- Very much *not* the same thing

给你。是的,它很容易实现,但这并不意味着您必须为每个项目手动实现它。

If you use next to traverse a table constructed with table.pack, it really ruins iteration.

是的,这就是您使用next迭代序列的原因。请改用 ipairs,这是它的意思。

  1. next 比 ipairs 慢(PUC 和 JIT)
  2. next 没有按顺序迭代
  3. 使用 ipairs 是 Lua 惯例

Oh and length operator won't count that n.

默认情况下它不会,但是您可以编写一个执行此操作的元方法,这真的没什么大不了的。

local meta = { __len = function(self) return self.n or rawlen(self) end }
print(#setmetatable(table.pack('a', 'b', nil, 'd', nil))) -- 5