Глубокое и поверхностное копирование
Реализуйте рекурсивное глубокое копирование и изучите семантику ссылок.
«Глубокое и поверхностное копирование» — бесплатный урок Lua Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Семантика ссылок в Lua
В Lua присваивание таблицы другой переменной копирует ссылку, а не данные. Обе переменные указывают на одну и ту же таблицу.
local a = {1, 2, 3}
local b = a
b[1] = 99
print(a[1]) -- 99, a is affected!Неглубокая копия
Неглубокая копия создаёт новую таблицу с теми же ключами и значениями верхнего уровня. Вложенные таблицы по-прежнему используются совместно.
local function shallowCopy(t)
local copy = {}
for k, v in pairs(t) do copy[k] = v end
return copy
endОграничение неглубокой копии
Изменение вложенной таблицы в неглубокой копии влияет на исходную таблицу.
local orig = {data = {1, 2, 3}}
local sc = shallowCopy(orig)
sc.data[1] = 99
print(orig.data[1]) -- 99 (shared!)Глубокая копия с помощью рекурсии
Глубокая копия рекурсивно дублирует каждую вложенную таблицу, устраняя все общие ссылки.
local function deepCopy(orig)
local copy
if type(orig) == "table" then
copy = {}
for k, v in pairs(orig) do
copy[deepCopy(k)] = deepCopy(v)
end
setmetatable(copy, getmetatable(orig))
else
copy = orig
end
return copy
endГлубокая копия в действии
После создания глубокой копии изменение вложенных таблиц в копии не затрагивает исходную таблицу.
local orig = {data = {1, 2, 3}}
local dc = deepCopy(orig)
dc.data[1] = 99
print(orig.data[1]) -- 1 (independent!)Обработка циклов
Наивное глубокое копирование не работает с циклическими таблицами. Отслеживайте посещённые таблицы в таблице памяти, чтобы обрабатывать циклы.
local function deepCopyMemo(orig, memo)
memo = memo or {}
if type(orig) ~= "table" then return orig end
if memo[orig] then return memo[orig] end
local copy = {}
memo[orig] = copy
for k, v in pairs(orig) do
copy[deepCopyMemo(k, memo)] = deepCopyMemo(v, memo)
end
setmetatable(copy, getmetatable(orig))
return copy
endКопирование метатаблиц
Глубокая копия должна также переносить метатаблицу с помощью setmetatable(copy, getmetatable(orig)), чтобы сохранить поведение ООП.
Неглубокая копия с помощью table.move
Для последовательных массивов быструю неглубокую копию можно создать с помощью table.move.
local function arrayCopy(t)
return table.move(t, 1, #t, 1, {})
endКогда что использовать
- Неглубокая: простые плоские таблицы, клонирование, критичное к производительности.
- Глубокая: вложенные структуры, сериализация, неизменяемые снимки состояния.
Значения-функции
Функции никогда не копируются: и неглубокая, и глубокая копия используют одну и ту же ссылку на функцию. Обычно это именно то поведение, которое требуется.
Особенности производительности
Глубокая копия работает за O(n), где n — количество узлов. Для очень больших деревьев вместо этого рассмотрите совместное использование структуры или шаблоны копирования при записи.
Вопрос о типе копии
Что произойдёт после неглубокого копирования, если изменить вложенную таблицу в копии?
Повторение: глубокая и неглубокая копия
Неглубокая копия дублирует только ключи верхнего уровня, а вложенные таблицы остаются общими. Глубокая копия рекурсивно дублирует всё. Обрабатывайте циклы с помощью таблицы памяти, чтобы предотвратить бесконечную рекурсию.
Часто задаваемые вопросы
Урок «Глубокое и поверхностное копирование» бесплатный?
Да — полный текст урока «Глубокое и поверхностное копирование» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Глубокое и поверхностное копирование»?
Реализуйте рекурсивное глубокое копирование и изучите семантику ссылок. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Глубокое и поверхностное копирование»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- table.sort с компараторами
- table.concat и table.move
- Глубокое и поверхностное копирование
- Преобразование таблиц: map, filter, reduce