Могу ли я заставить индексирование таблицы 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, я надеюсь, что сделаю сам явный <, <