Вопрос
Во многих языках вы можете объединять строки при присвоении переменной.У меня есть сценарий, использующий язык программирования Lua, где мне нужно добавить выходные данные команды к существующей переменной.Существует ли в Lua функциональный эквивалент приведенным ниже примерам?
Примеры других языков:
===== PERL =====
$filename = "checkbook";
$filename .= ".tmp";
================
===== C# =====
string filename = "checkbook";
filename += ".tmp";
===============
Заранее благодарю вас за вашу помощь.
Решение
Как говорилось в других ответах, оператор конкатенации строк в Lua состоит из двух точек.
Ваш простой пример был бы написан следующим образом:
filename = "checkbook"
filename = filename .. ".tmp"
Однако есть один нюанс, о котором следует знать.Поскольку строки в Lua неизменяемы, каждая конкатенация создает новый объект string и копирует в него данные из исходных строк.Это приводит к тому, что последовательные объединения с одной строкой имеют очень низкую производительность.
Идиома 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
также может быть сохранено как значение) поиск строкового представления оставлен в качестве упражнения для учащегося.И не забывайте о деревьях и более сложных структурах таблиц.
Другие советы
Если вы спрашиваете, существует ли сокращенная версия оператора ..
, то нет. Вы не можете написать a .. = b
. Вам нужно будет ввести его полностью: filename = filename .. " .tmp "
Конкатенация:
Оператор конкатенации строк в Lua обозначается двумя точками ('..'). Если оба операнда являются строками или числами, они преобразуются в строки в соответствии с правилами, указанными в 2.2.1. В противном случае, «concat» Метаметод называется (см. & # 167; 2.8). Р>
Строки можно объединить с помощью оператора конкатенации " .. "
это то же самое для переменных, я думаю,