Lua 的长度运算符的特殊规范让我想知道 Lua 是否会“允许”在类似的情况下返回负值
#{[-5]=1,[-1]=3}
它说:
表的长度
t
定义为任何整数索引n
,例如t[n]
is notnil
和t[n+1]
isnil
;
n=-5
n=-1
在我的例子中会满足这个标准,对吧?
此外,如果
t[1]
是nil
,n
则可以为零。
对,它可以为零,但不能保证,对吧?
对于从 1 到给定 n 的非 nil 值的常规数组,它的长度正好是 n,它的最后一个值的索引。
这不是这里的情况,所以它不适用。
如果数组有“洞”(即
nil
其他非 nil 值之间的值),那么 #t 可以是任何直接在nil
值之前的索引(也就是说,它可以将任何这样nil
的值视为数组的末尾)。
这里就是这种情况,所以再次,n=-5
并且n=-1
将是有效的返回值,对吗?
我可以完全确定 Lua 总是为示例表或任何其他只包含负索引的表返回 0 吗?如果(假设)我正在编写一个 Lua 解释器并返回其中任何一个值,我会符合规范吗?
编辑
显然,Lua 的实现方式,它不会返回负值。我觉得长度运算符的文档有些不足,我看到 Lua 5.2 的文档已经改变。它现在说:
除非
__len
给出元方法,否则t
只有当表是一个序列时才定义表的长度,也就是说,对于某个整数n,其正数字键的集合等于{1..n}。在这种情况下,n是它的长度。请注意,像{10, 20, nil, 40}
不是序列,因为它有 key
4
但没有 key3
。
所以,它现在谈论的是正数字键,这就更清楚了。我很聪明,但对文档并不完全满意。当它说“只有在表是序列时才定义长度”时,它还应该说明即使表不是序列也会返回值,但行为是未定义的。此外,这个表看起来很像一个序列:
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
然而,这变得越来越挑剔,因为很明显,考虑到__index
可能造成的混乱是没有意义的。Stackoverflow 肯定不是抱怨文档可能更精确的地方。