Lua таблица со строковыми ключами не работает с индексацией чисел? - PullRequest
0 голосов
/ 01 сентября 2018

Я новичок в Lua.

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

Мой код:

local t = {}
t.name = "John"
t.age = 30
print("Name : " .. t.name .. "\nAge : " .. t.age)

Хотя этот код работает нормально и печатает ожидаемый результат,

Name : John
Age : 30

Если я попытаюсь напечатать результат таким образом,

print("Name : " .. t[1] .. "\nAge : " .. t[2])

Я получаю следующую ошибку:

lua: main.lua:5: attempt to concatenate a nil value (field '?')
stack traceback:
    main.lua:5: in main chunk
    [C]: in ?

Означает ли это, что я не могу перебрать таблицу, используя for с индексацией чисел, без необходимости знать строки ключей?

Если да, то есть ли что-то, чтобы заставить работать оба пути?

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

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

local mt = { __index = function(t, n)
                 assert(n > 0)
                 for k, v in pairs(t) do
                     n = n - 1
                     if n == 0 then
                         return v
                     end
                 end
           end }

local t = {}
setmetatable(t, mt)
t.name = "John"
t.age = 30
print("Name : " .. t.name .. "\nAge : " .. t.age)
print("Name : " .. t[1] .. "\nAge : " .. t[2])

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

$ lua test.lua 
Name : John
Age : 30
Name : John
Age : 30
$ lua test.lua 
Name : John
Age : 30
Name : 30
Age : John
0 голосов
/ 01 сентября 2018

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

print("Name : " .. t["name"] .. "\nAge : " .. t["age"])

Вы можете перебирать пары ключ-значение в таблице, используя функцию pairs следующим образом:

for k, v in pairs(t) do
    print(k, v)
end

Если вы хотите использовать индексы вместо ключей строк, вы можете настроить его следующим образом:

local t = {
    "John",
    30,
}
print("Name : " .. t[1].. "\nAge : " .. t[2])

Когда вы делаете это таким образом, значения в таблице t имеют целочисленные индексы, автоматически назначаемые каждому значению. Если вы хотите перебирать их один за другим, вы можете перебирать их с помощью ipairs:

for i, v in ipairs(t) do
    print(i, v)
end
...