Сначала посмотрим на исходный код получения длины таблицы Lua (ltable.c)

j — это длина массивной части. Сначала, если длина массива больше 0 и последний элемент массива равен nil, используется бинарный поиск для нахождения и возврата длины.

Если t->node хранит хеш-часть таблицы, и если она пуста, возвращается длина массива.

Первый пример:

В этом случае длина массива инициализирована, и длина t равна 7. Почему? Потому что последний элемент не nil.

В следующем случае длина t равна 5.

Второй пример:

Всем должно быть известно, что длина t равна 5.

В этом случае какова длина t???

Ответ — 2. Почему?

Вставка t

t

Затем он войдёт в (lvm.c)

Затем он вызовет функцию luaH_newkey в (ltable.c)

Затем он вызывает rehash

Эта часть фактически представляет собой вычисление части массива и того, что попадает в хеш-часть. nums — это распределение статистики. Если вы внимательно посмотрите на код, то узнаете, что длина массива — это 2 в степени n.

Здесь nil не является числом и не включается в статистику, поэтому для 1, 2, 5 и 6 длина массива будет вычислена как 4, а остальное будет помещено в часть node.

Таблица состоит из массива и хеш-части node.

Таким образом, согласно функции, которую мы рассматривали ранее, четвёртый элемент — nil, поэтому длина, найденная с помощью бинарного поиска, равна 2.

Это ловушка, которая может возникнуть, если в массиве Lua есть nil. Конечно, она возникает только из-за rehash.

Оригинальный адрес: https://www.cnblogs.com/wallini/p/4188499.html