まず lua table のソースコードの長さ取得部分(ltable.c)を見てみましょう
j は配列部分の長さです。まず配列の長さが 0 より大きく、かつ配列の最後の要素が nil の場合、二分探索で長さを探して返します。
t->node が table の hash 部分の格納場所です。もし空であれば、配列の長さを返します。
最初の例:
この場合、配列の長さが初期化されていて、t の長さは 7 です。なぜでしょうか。最後の要素が nil ではないからです。
以下の場合、t の長さは 5 です。
2番目の例:
誰でも t の長さが 5 であることは分かるでしょう。
この場合、t の長さはいくつでしょうか???
答えは 2 です。なぜでしょうか?
t
t
次に(lvm.c)に入ります
次に(ltable.c)の luaH_newkey 関数を呼び出します
そして rehash を呼び出します
この部分は実際には配列部分と hash 部分に格納する計算です。nums は数値の分布を統計しています。コードをよく見ると、配列の長さは 2 の n 乗であることが分かります。
ここで nil は数値ではないため統計に含まれません。よって 1、2、5、6 から配列の長さは 4 と計算され、残りの部分は node 部分に格納されます。
table は配列と node hash 部分から構成されています。
このように、先ほど見た関数によると、4番目が nil なので、二分探索で求められる長さは 2 です。
これが lua 配列内に nil がある場合に起こり得る落とし穴です。もちろん rehash が原因です。
原文アドレス:https://www.cnblogs.com/wallini/p/4188499.html