好吧,special specification of Lua's length operator让我想知道Lua是否会被“允许”在像
这样的情况下返回负值#{[-5]=1,[-1]=3}
它说:
在我的示例中,表
t
的长度定义为任何整数索引n
,使t[n]
不是nil
和{{1是t[n+1]
;
nil
和n=-5
符合此标准,对吗?
此外,如果
n=-1
t[1]
,则nil
可以为零。
是的,它可以为零,但不能保证,对吗?
对于常规数组,非n值从1到给定n,其长度恰好是n,即其最后一个值的索引。
这不是这种情况,因此不适用。
如果数组有“空洞”(即
n
之间的其他非零值),则#t可以是直接位于nil
值(也就是说,它可以将任何此类nil
值视为数组的结尾)。
这是这种情况,所以nil
和n=-5
将是有效的返回值,对吗?
我可以完全确定Lua总是为示例表或任何其他仅包含负索引的表返回0吗?如果(假设)我会写一个Lua解释器并返回其中任何一个值,我是否符合规范?
修改
显然,Lua的实现方式,它不会返回负值。我觉得长度操作符有点不详,我看到Lua 5.2的文档已经改变了。它现在说:
除非给出
这样的表格n=-1
元方法,否则仅在表为序列时定义表__len
的长度,即其正数的集合对于某些整数 n ,键等于 {1..n} 。在这种情况下, n 是它的长度。请注意像t
不是序列,因为它具有键
{10, 20, nil, 40}
但没有键4
。
所以,它现在谈论正面数字键,这更加清晰。我更加明智但对文档并不完全满意。当它表示“仅在表是序列时定义了长度”时,它还应声明即使表不是序列,也返回值,但行为未定义。此外,该表看起来非常像一个序列:
3
然而,这已经成为挑剔,因为很明显,考虑到a = setmetatable(
{0},
{
__index = function(t,k)
return k < 10 and k or nil
end
}
)
i = 1
while a[i] do
print(a[i])
i = i+1
end
--[[ prints:
0
2
3
4
5
6
7
8
9
]]
print(#a)
-- prints: 1
可能产生的混乱是没有意义的。并且Stackoverflow当然不是抱怨可能更精确的文档的地方。
答案 0 :(得分:1)
如您所知,长度运算符的规格已在5.1和5.2之间变化。
我可以完全确定Lua总是为示例表或任何其他仅包含负索引的表返回0吗?
您可以使用当前的参考实现,确保ilen
已定义
function ilen (xs)
local i=0
while xs[i+1] do i=i+1 end
return i
end
我们总是#xs >= ilen(xs)
- 请参阅the ltable.c
source中luaH_getn的定义。但是规范现在故意不承诺这种行为:一致的实现可以返回nil
或者为尝试查找不是序列的表的长度引发异常。
答案 1 :(得分:0)
来自参考链接中的文字。答案是否定的。
我认为你混淆了这样一个事实:如果找到NIL,那么表的长度被认为是NIL被发现-1的位置。
因此,如果t(1)为NIL,则1 - 1 = 0,因此表长度为0。
如果一个表的长度为5,则下一个位置或t(6)为IS或者为NIL
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero.