2013-04-15 2 views
2

, ну, special specification of Lua's length operator заставило меня задаться вопросом Lua будет «разрешено» возвращать отрицательное значение в ситуации, какМожет ли оператор длины Lua возвращать отрицательный индекс?

#{[-5]=1,[-1]=3} 

Он говорит:

Длина стола t определяется чтобы быть любым целым индексом n таким образом, что t[n] не nil и t[n+1] является nil;

n=-5 и n=-1 соответствует моему критерию в моем примере, не так ли?

кроме того, если это t[1]nil, n может быть равен нулю.

Право, это может быть равен нулю, но это не гарантировано, верно?

Для регулярного массива с не-nil значениями от 1 до заданного n его длина точно равна n, индексу последнего значения.

Это не тот случай, поэтому он не применяется.

Если массив имеет «дыры» (то есть, nil значения между другими значениями, не ноль), то #t может быть любой из индексов, которые непосредственно предшествует значение по nil (то есть, он может рассматривать любое такое значение nil как конец массива).

Это тот случай, так что опять, n=-5 и n=-1 бы действительные возвращаемые значения, не так ли?

Могу ли я быть полностью уверенным, что Lua всегда возвращает 0 для таблицы примеров или любую другую таблицу, содержащую только отрицательные индексы? Если (гипотетически) я буду писать интерпретатор Lua и вернусь к любому из этих значений, буду ли я соответствовать спецификациям?

Редактировать

Очевидно, что путь Lua реализован, он не возвращает отрицательные значения. Я чувствовал, что оператор длины несколько недооценен, и я вижу, что документация Lua 5.2 изменилась. Он теперь говорит:

За исключением случаев, __len Метаметод не дается, длина таблицы t определяется только если таблица является последовательность, то есть множество его положительных цифровых клавиш равно { 1..n} для целого числа n.В этом случае n - его длина. Обратите внимание, что таблица, как

{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 

Однако это становится придирки, поскольку это довольно ясно, что это не имеет смысла принимать во внимание то, что беспорядок __index может сделать. И Stackoverflow, конечно, не место, чтобы жаловаться на документацию, которая может быть более точной.

+0

Учитываются только положительные целочисленные индексы. Отрицательные, дробные и нечисловые индексы могут содержать все, что не влияет на длину, возвращаемую оператором '#'. Возможно, руководство Lua должно быть изменено, чтобы быть более понятным. –

+3

«... также должно быть указано, что даже если таблица не является последовательностью, возвращается значение, но поведение * не определено». Если поведение не определено, все ставки отключены, и это необязательно смысл сказать, что возвращается значение. –

ответ

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) - смотрите определение luaH_getn в the ltable.c source. Но спецификация теперь намеренно не обещает этого поведения: соответствующая реализация может вернуть nil или поднять исключение для попыток найти длину таблиц, которые не являются последовательностями.

0

Из текста в справочной ссылке. Ответ - нет.

Я думаю, что вы сбиваете с толку тот факт, что если найден NIL, то длина таблицы считается позицией NIL, найденной -1.

Поэтому, если т (1) равен нулю, то 1 - 1 = 0, так что длина таблицы 0.

Если длина таблицы было 5, то следующей позиции или т (6) или будут 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. 
+0

По этой логике, если я найду нуль в индексе 100, то в качестве разработчика я бы позволил вернуть 99. Это явно неточно. –

+0

Разве это не подразумевается?потому что, если вы нашли NIL в 100, тогда возврат будет равен 99, и это будет соответствовать следующему: «Длина таблицы t определяется как любой целочисленный индекс n, такой, что t [n] не равен nil и t [n + 1] равен nil " – Zeddy

+0

Нет, это не так, потому что для' n = 99' 't [n]' * is * 'nil', но требуется, чтобы он был * not *' nil'. –

Смежные вопросы