在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 实现的答案。
在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 实现的答案。
从 1 开始的连续整数键始终位于数组部分。
不是正整数的键总是放在散列部分。
除此之外,它是未指定的,因此您无法t[5]
根据规范预测将存储在哪里(它可能会或可能不会在两者之间移动,例如,如果您创建然后删除t[4]
。)
LuaJIT 2 略有不同——它也会存储t[0]
在数组部分。
如果您需要它是可预测的(这可能是一种设计味道),请坚持使用纯数组表(从 1 开始的连续整数键 - 如果您想留出间隙,请使用值 offalse
代替nil
)或纯哈希表(避免非-负整数键。)
引用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]
将转到数组部分。