Сначала посмотрим на исходный код получения длины таблицы 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