4

在Lua 5.0的实现的第 4 节,表格中,有一个例子:
local t = {100, 200, 300, x = 9.3}

所以我们有t[4] == nil. 如果我写t[0] = 0,这将去散列部分
如果我写t[5] = 500它会去哪里?数组部分还是散列部分
如果有区别,我很想听到 Lua 5.1、Lua 5.2 和 LuaJIT 2 实现的答案。

4

2 回答 2

2

从 1 开始的连续整数键始终位于数组部分。

不是正整数的键总是放在散列部分。

除此之外,它是未指定的,因此您无法t[5]根据规范预测将存储在哪里(它可能会或可能不会在两者之间移动,例如,如果您创建然后删除t[4]。)

LuaJIT 2 略有不同——它也会存储t[0]在数组部分。

如果您需要它是可预测的(这可能是一种设计味道),请坚持使用纯数组表(从 1 开始的连续整数键 - 如果您想留出间隙,请使用值 offalse代替nil)或纯哈希表(避免非-负整数键。)

于 2013-07-10T12:54:56.820 回答
1

引用Lua 5.0 的实现

数组部分尝试存储对应于从 1 到某个限制 n 的整数键的值。对应于非整数键或数组范围之外的整数键的值存储在哈希部分中。

数组部分的索引从 1 开始,这就是为什么t[0] = 0会去散列部分。

数组部分的计算大小是最大的 n,使得 1 和 n 之间的插槽至少有一半正在使用(避免稀疏数组浪费空间),并且在 n/2+1 和 n(当 n/2 可以时避免大小 n)。

根据此规则,在示例表中:

local t = {100, 200, 300, x = 9.3}

包含 3 个元素的数组部分的大小可能为 3、4 或 5。(编辑:大小应为 4,请参阅@dualed 的评论。)

假设数组的大小为4,写入时t[5] = 500,数组部分不能再容纳元素t[5],如果数组部分调整为8怎么办?大小为 8 时,数组部分包含 4 个元素,等于(因此,不少于)数组大小的一半。并且在 n/2+1 和 n 之间的索引(在这种情况下为 5 到 8)具有一个元素:t[5]。所以数组大小为 8 就可以满足要求。在这种情况下,t[5]将转到数组部分。

于 2013-07-10T13:05:02.600 回答