Могу ли я заставить индексирование таблицы Lua с нуля?

Я читал о Lua, это почти идеальный язык, но была критическая ошибка. Это однонаправленное индексирование. Я также читал, что он имеет функцию установки значения в индексе 0, но он не учитывает длину таблицы, а строковые манипуляции по-прежнему основаны на одном. Таким образом, функция не имеет смысла.

Я не хочу плакать вокруг основанного на основе нуля или нуля. Я просто спрашиваю, есть ли функция, вынуждающая использовать индексирование с нулевым индексом.

Ответ 1

Я думаю, что у Lua уже есть функция, которую вам нужно сделать на основе 0. К сожалению, эта функция, на которую я ссылаюсь, является лицензией с открытым исходным кодом Lua.

Мне не удалось найти патч или вилку Lua, которые изменили характер языка на основе 1.

К сожалению, форсирование Lua, чтобы изменить его на 0, также нарушит совместимость. Потеря всех существующих дополнительных модулей может быть слишком большой ценой для удобства использования.

Ответ 2

Я знаю, что этот вопрос уже 1 год, но я думал, что будущим искателям будет интересно узнать, что CFF Explorer содержит язык сценариев (Lua с исправлениями), который имеет 0-индексированный патч таблицы:

http://www.ntcore.com/files/cffscriptv2.htm

Кроме того, в вышеприведенном документе автор заявил, что ему пришлось отключить большинство стандартных функций библиотеки, поскольку они несовместимы с массивами с 0 индексами, поэтому, пожалуйста, повторите свой мыслительный процесс по этой проблеме:)

Ответ 3

Работа с 0-индексированными массивами на самом деле довольно проста:

local array={
[0]="zero",
    "one",
    "two"
}

for i=0,#array do
    print(array[i])
end

Вы можете использовать #array без вычитания 1, потому что оператор длины фактически возвращает наивысший индекс (технически ключ до первого нуля), а не фактическую "длину" (что в любом случае не имеет смысла в Lua).

Для строковых операторов вам, вероятно, придется просто создавать повторяющиеся функции (хотя может быть и лучший способ)

ipairs() также поддерживает только 1 индексацию, но вы можете просто использовать обычный for, который, как мне кажется, более читабельным:

for _,element in ipairs(array1) do
    print(element)
end
for i=0,#array0 do
    local element=array0[i]
    print(element)
end

Ответ 4

Даже если в источниках Lua был #define TABLE_START_INDEX 1 (который, как я полагаю, нет), вы бы очень стреляли в ногу, изменив это. Это объясняется тем, что большинство библиотек используют индексирование на основе 1. Таким образом, любой код, делающий что-то вроде следующего, сломается.

для я = 1, #t do... end

Вы можете, конечно, использовать итераторы или даже создавать вспомогательные функции, чтобы этого избежать.

функция get_first (t) return t [1] end

Вероятно, хотя фактическая проблема, которую вы пытаетесь решить, сложнее, чем изменение индексации от 0 до 1.

Ответ 5

Комментарий Eonil для ответа ponzao: реальной проблемой является базовый язык, который должен быть C, который является индексирующим языком на основе 0. Преобразование данных индексирования между script и хостом должно быть правильно переведено.

Если вы хотите выставить структуры данных C в Lua, используйте userdata, чтобы упаковать их. Вы можете заставить индексирование вести себя, как вам нравится, используя метатеги. Таким образом, вы можете обеспечить правильный перевод.

Ответ 6

Грязный подход с некоторыми недостатками:

function zeroIndexed(tbl)
    local mt = {}
    mt.data = tbl
    mt.__index = function(t, k)
        return mt.data[(type(k) == "number" and k + 1 or k)]
    end
    mt.__newindex = function(t, k, v)
        mt.data[(type(k) == "number" and k + 1 or k)] = v
    end
    mt.__len = function()
        return #mt.data
    end
    return setmetatable({}, mt)
end
t = zeroIndexed({5, 6, 7})
print(t[0], t[1], t[2])
t[0] = 4
print(t[0], #t)
t[#t] = 8
print(t[#t - 1], #t)

Выходы Lua 5.2:

5       6       7
4       3
8       4

В Lua 5.1 #t возвращает 0, потому что __len metamethod не соблюдается для таблиц и строк.

Но помните, что table.insert и другие методы таблицы больше не будут работать здесь, потому что вставка теперь выполняется через t[#t] = x.

Я не рекомендую использовать это.

Ответ 7

Вы можете исправить эту ошибку, используя итератор, который знает разные базы индексов:

function iarray(a)
  local n = 0
  local s = #a
  if a[0] ~= nil then
    n = -1
  end
  return function()
    n = n + 1
    if n <= s then return n,a[n] end
  end
end

Однако вам все равно придется добавить нулевой элемент вручную:

Пример использования:

myArray = {1,2,3,4,5}
myArray[0] = 0
for _,e in iarray(myArray) do
  -- do something with element e
end

Ответ 8

ответ на ваш запрос его нет, theres не способ заставить весь процесс, который lua обрабатывает с индексом 0, потому что прямо сейчас, насколько я знаю #table идет от 1, "n" и без него индекс 0 его почти бесполезно, на мой взгляд, но зависит от того, что вы хотите сделать, вы можете сравнить, есть ли у вас что-то или нет, от таблиц 1, которые читают продукты 1, которые читают доход, и если продукты увеличиваются, у вас будет больше, если у вас есть = 1, то у вас есть nil, поэтому вы просто читаете 1 таблицу, а не 2, я надеюсь, что сделаю сам явный <, <