2010-08-07 3 views
11

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

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

+1

Может ли я просто спросить, почему это проблема? Итак, вы предпочитаете 0-индексирование, но почему вы не можете работать с 1-индексированием? – gnud

+3

У меня тоже есть эта проблема :) Независимо от того, что имеет смысл, я получаю это неправильно в lua почти каждый раз. Я так привык к работе с другими языками, которые основаны на нулевом значении, потому что мой код lua полон ошибок из-за одной только этой вещи! – jcoder

+0

Я не думаю, что есть какой-то флаг, который бы переключил lua от 1 до 0 и как таковой, кроме изменения lua, которые требуют использования нестандартного lua (я здесь dub lua0), я не вижу, как это будет сделано –

ответ

2

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

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

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

+0

Кажется, нет простого способа отменить это поведение. – Eonil

1

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

для я = 1, #t сделать ... конец

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

функция get_first (т) возвращение т [1] конец

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

+3

Нет. Это не проблема. Реальной проблемой является базовый язык, который должен быть C, который является индексирующим языком на основе 0. Индексирование обмена данными между скриптом и хостом должно быть правильно переведено. И мне приходится одновременно обращаться с двойной системой индексирования. – Eonil

3

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

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

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

1

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

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

-1

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

1

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

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.

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

+0

Почему бы вам не порекомендовать? для проблемы с табличной вставкой? –

+0

У этого есть проблема: итераторы ipairs и pair будут по-прежнему возвращать индексы для массивов на 1 основе. – val

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 
0

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

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 
Смежные вопросы