Странная ошибка таблицы в Lua - PullRequest
2 голосов
/ 26 августа 2011

Хорошо, у меня странная проблема со следующим кодом Lua:

function quantizeNumber(i, step)
    local d = i / step
    d = round(d, 0)
    return d*step
end

bar = {1, 2, 3, 4, 5}

local objects = {}
local foo = #bar * 3
for i=1, #foo do
    objects[i] = bar[quantizeNumber(i, 3)]
end
print(#fontObjects)

После запуска этого кода длина объектов должна быть 15, верно? Но нет, это 4. Как это работает и чего мне не хватает?

Спасибо, Эллиот Бонневиль.

Ответы [ 2 ]

5 голосов
/ 26 августа 2011

Да, это 4.

Из справочного руководства Lua:

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

Давайте изменим код, чтобы увидеть, что находится в таблице:

local objects = {}
local foo = #bar * 3
for i=1, foo do
    objects[i] = bar[quantizeNumber(i, 3)]
    print("At " .. i .. " the value is " .. (objects[i] and objects[i] or "nil"))
end
print(objects)
print(#objects)

Когда вы запустите это, вы увидите, что objects[4] - это 3, но objects[5] это nil.Вот результат:

$ lua quantize.lua 
At 1 the value is nil
At 2 the value is 3
At 3 the value is 3
At 4 the value is 3
At 5 the value is nil
At 6 the value is nil
At 7 the value is nil
At 8 the value is nil
At 9 the value is nil
At 10 the value is nil
At 11 the value is nil
At 12 the value is nil
At 13 the value is nil
At 14 the value is nil
At 15 the value is nil
table: 0x1001065f0
4

Это правда, что вы заполнили 15 слотов таблицы.Однако оператор # для таблиц, как определено в справочном руководстве, не заботится об этом.Он просто ищет индекс, значение которого не равно нулю, а следующий индекс равен ноль.

В этом случае индекс, удовлетворяющий этому условию, равен 4.

Вот почему ответ 4. Это просто способ, которым Lua.

Ноль можно рассматривать как представляющий конец массива.Это похоже на то, как в C нулевой байт в середине массива символов на самом деле конец строки , а "string" - это только те символы перед ним.

Если вашнамеревался создать таблицу 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5, тогда вам нужно будет переписать вашу quantize функцию следующим образом:

function quantizeNumber(i, step)
    return math.ceil(i / step)
end
0 голосов
/ 26 августа 2011

Функция quantizeNumber неверна. Вы ищете функцию math.fmod:

objects[i] = bar[math.fmod(i, 3)]
...