可能Lua的长度算子返回负指数?

时间:2013-04-15 18:02:51

标签: lua

好吧,special specification of Lua's length operator让我想知道Lua是否会被“允许”在像

这样的情况下返回负值
#{[-5]=1,[-1]=3}

它说:

  

t的长度定义为任何整数索引n,使t[n]不是 nil 和{{1是 t[n+1] ;

在我的示例中,

niln=-5符合此标准,对吗?

  

此外,如果n=-1 t[1] ,则nil可以为零。

是的,它可以为零,但不能保证,对吗?

  

对于常规数组,非n值从1到给定n,其长度恰好是n,即其最后一个值的索引。

这不是这种情况,因此不适用。

  

如果数组有“空洞”(即 n 之间的其他非零值),则#t可以是直接位于 nil 值(也就是说,它可以将任何此类 nil 值视为数组的结尾)。

这是这种情况,所以niln=-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当然不是抱怨可能更精确的文档的地方。

2 个答案:

答案 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.