先来看 lua table 源码长度获取部分(ltable.c)

1534300954-1587-201412-.png

j 是数组部分的长度。首先判断数组长度大于 0 并且数组最后个是 nil 就用二分法查找 返回长度。

如果 t->node 是 table 的 hash 部分存放 如果是空 就返回数组的长度。

第一种例子:

1534300937-7318-201412-.png

对于这种 初始化了数组长度 t 的长度是 7 为什么呢。因为最后一位不是 nil

以下情况 t 的长度就是 5。

1534300936-7519-201412-.png

第二种例子:

1534300936-9535-201412-.png

大家都应该知道 t 的长度是 5。

这样的话 t的长度是多少呢???

答案是 2 为什么呢?

对于 t[6] 的插入 导致 table 表 rehash。

t[6] 会先调用(lapi.c)

1534300937-8505-201412-.png

然后会进入(lvm.c)

1534300938-6429-201412-.png

然后会调用(ltable.c)luaH_newkey这个函数

1534300938-1759-201412-.png

然后调用 rehash

1534300939-6064-201412-.png

这个地方其实是数组部分和放到hash部分的计算 nums 是统计数字的分布,仔细看代码会知道数组长度是 2 的 n 次方。

这儿 nil 不是数字不会纳入统计 所以 1 2 5 6 会计算出数组长度是 4 其余部分放入到 node 部分

1534300939-5801-201412-.png

table 是有数组和 node hash 部分组成。

这样根据 前面看的函数 第四个是 nil 所以用二分法找出的长度是 2。

这样是 lua 数组里面如果 nil 可能会导致的坑 当然只是 rehash 导致的。

原文地址:https://www.cnblogs.com/wallini/p/4188499.html