为什么Lua的长度(#)运算符返回意外值?

前端之家收集整理的这篇文章主要介绍了为什么Lua的长度(#)运算符返回意外值?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Lua具有#运算符来计算用作数组的表的“length”.
我检查了这个运算符,我很惊讶.

这是我在Lua 5.2.3下运行的代码

t = {};
t[0] = 1;
t[1] = 2;
print(#t); -- 1 aha lua counts from one
t[2] = 3;
print(#t); -- 2 tree values,but only two are count
t[4] = 3;
print(#t); -- 4  but 3 is mssing?
t[400] = 400;
t[401] = 401;
print(#t); -- still 4,now I am confused?


t2 = {10,20,nil,40}
print(#t2); -- 4 but documentations says this is not a sequence?

有人可以解释规则吗?

解决方法

引用Lua 5.2参考手册:
the length of a table t is only defined if the table is a sequence,that is,the set of its positive numeric keys is equal to {1..n}
for some integer n

非序列上的#运算符的结果未定义.
what happens in C implementation of Lua when we call # on a non-sequence

背景:Lua中的表格内部分为数组部分和散列部分.这是一个优化. Lua试图避免经常分配内存,所以它预先分配两个下一个权力.这是另一个优化.

>当数组部分的最后一个项为nil时,#的结果是通过bin搜索第一个nil-follow键的数组部分找到的最短有效序列的长度.
>当数组部分中的最后一项不为零且散列部分为空时,#的结果是数组部分的物理长度.
>当数组部分中的最后一项不为零且散列部分不为空时,#的结果是通过bin搜索第一个零跟随键的哈希部分找到的最短有效序列的长度(就是这样正整数i,t [i]〜= nil和t [i 1] == nil),假设数组部分是非nils(!).

所以#的结果几乎总是最短有效序列的(期望的)长度,除非表示非序列的数组部分中的最后一个元素是非零的.那么结果比想要的要大.

这是为什么?这似乎是另一个优化(对于两个大小的数组).这种表上的#的复杂度是O(1),而其他变体是O(log(n))).

猜你在找的Lua相关文章