Ответ 1
Как говорили другие ответы, оператор конкатенации строк в Lua - две точки.
Ваш простой пример будет написан следующим образом:
filename = "checkbook"
filename = filename .. ".tmp"
Однако есть оговорка, о которой нужно знать. Поскольку строки в Lua неизменяемы, каждая конкатенация создает новый строковый объект и копирует данные из исходных строк в него. Это приводит к тому, что последовательные конкатенации в одну строку имеют очень низкую производительность.
Идиома Lua для этого случая выглядит примерно так:
function listvalues(s)
local t = { }
for k,v in ipairs(s) do
t[#t+1] = tostring(v)
end
return table.concat(t,"\n")
end
Собирая строки, которые будут объединены в массив t
, стандартную библиотечную подпрограмму table.concat
можно использовать для объединения всех них (вместе с разделительной строкой между каждой парой) без ненужного копирования строк.
Обновление: Я только заметил, что я изначально написал фрагмент кода выше, используя pairs()
вместо ipairs()
.
Как первоначально было написано, функция listvalues()
действительно вывела бы каждое значение из таблицы, переданной, но не в стабильном или предсказуемом порядке. С другой стороны, это будет включать значения, ключи которых не были целыми положительными в диапазоне от 1
до #s
. Это то, что делает pairs()
: он производит каждую пару (ключ, значение), хранящуюся в таблице.
В большинстве случаев, когда вы использовали бы что-то вроде listvaluas()
, вам было бы интересно сохранить их порядок. Таким образом, вызов, написанный как listvalues{13, 42, 17, 4}
, выдает строку, содержащую это значение в этом порядке. Однако pairs()
не будет этого делать, он будет перечислять их в определенном порядке, что зависит от базовой реализации структуры данных таблицы. Известно, что порядок зависит не только от ключей, но и от того, в каком порядке были вставлены ключи и удалены другие ключи.
Конечно, ipairs()
тоже не является идеальным ответом. Он перечисляет только те значения таблицы, которые образуют "последовательность". То есть те значения, ключи которых образуют непрерывный блок, охватывающий от 1 до некоторой верхней границы, который (как правило) также является значением, возвращаемым оператором #
. (Во многих случаях сама функция ipairs()
лучше заменяется более простым циклом for
, который рассчитывается только от 1
до #s
. Это рекомендуемая практика в Lua 5.2 и LuaJIT, где более простой for
цикл может быть более эффективно реализован, чем итератор ipairs()
.)
Если pairs()
действительно правильный подход, обычно бывает так, что вы хотите напечатать как ключ, так и значение. Это уменьшает беспокойство по поводу порядка, делая самоописание данных. Конечно, поскольку любой тип Lua (кроме nil
и плавающей запятой NaN
) может использоваться как ключ (и NaN
также может быть сохранен как значение), поиск строкового представления остается как упражнение для студент. И не забывайте о деревьях и более сложных структурах таблиц.