在第4节“表格”中,在Implementation of Lua 5.0中有例子:
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实现的答案。
答案 0 :(得分:2)
从1开始的连续整数键总是进入数组部分。
非正整数的键总是进入散列部分。
除此之外,它是未指定的,因此您无法根据规范预测t[5]
的存储位置(它可能会也可能不会在两者之间移动,例如,如果您创建然后删除{{1 }}。)
LuaJIT 2略有不同 - 它还会在数组部分中存储t[4]
。
如果你需要它是可预测的(这可能是一种设计气味),坚持使用纯数组表(从1开始的连续整数键 - 如果你想留下间隙使用值t[0]
而不是false
)或纯哈希表(避免使用非负整数键。)
答案 1 :(得分:1)
引用 Lua 5.0的实现
数组部分尝试将对应于整数键的值从1存储到某个限制n。对应于非整数键或数组范围外的整数键的值是 存储在哈希部分。
数组部分的索引从1开始,这就是t[0] = 0
将转到哈希部分的原因。
数组部分的计算大小是最大的,使得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]
将转到数组部分。