问题
In section 4, Tables, in The Implementation of Lua 5.0 there is and example:local t = {100, 200, 300, x = 9.3}
So we have t[4] == nil
. If I write t[0] = 0
, this will go to hash part.
If I write t[5] = 500
where it will go? Array part or hash part?
I would eager to hear answer for Lua 5.1, Lua 5.2 and LuaJIT 2 implementation if there is difference.
回答1:
Contiguous integer keys starting from 1 always go in the array part.
Keys that are not positive integers always go in the hash part.
Other than that, it is unspecified, so you cannot predict where t[5]
will be stored according to the spec (and it may or may not move between the two, for example if you create then delete t[4]
.)
LuaJIT 2 is slightly different - it will also store t[0]
in the array part.
If you need it to be predictable (which is probably a design smell), stick to pure-array tables (contiguous integer keys starting from 1 - if you want to leave gap use a value of false
instead of nil
) or pure hash tables (avoid non-negative integer keys.)
回答2:
Quoting from Implementation of Lua 5.0
The array part tries to store the values corresponding to integer keys from 1 to some limit n.Values corresponding to non-integer keys or to integer keys outside the array range are stored in the hash part.
The index of the array part starts from 1, that's why t[0] = 0
will go to hash part.
The computed size of the array part is the largest nsuch that at least half the slots between 1 and n are in use (to avoid wasting space with sparse arrays) and there is at least one used slot between n/2+1 and n(to avoid a size n when n/2 would do).
According from this rule, in the example table:
local t = {100, 200, 300, x = 9.3}
The array part which holds 3 elements, may have a size of 3, 4 or 5. (EDIT: the size should be 4, see @dualed's comment.)
Assume that the array has a size of 4, when writing t[5] = 500
, the array part can no longer hold the element t[5]
, what if the array part resize to 8? With a size of 8, the array part holds 4 elements, which is equal to (so, not less that) half of the array size. And the index from between n/2+1 and n, which in this case, is 5 to 8, has one element:t[5]
. So an array size of 8 can accomplish the requirement. In this case, t[5]
will go to the array part.
来源:https://stackoverflow.com/questions/17570506/lua-understanding-table-array-part-and-hash-part