0Pricing
Lua Academy · Урок

Глубокое и поверхностное копирование

Реализуйте рекурсивное глубокое копирование и изучите семантику ссылок.

«Глубокое и поверхностное копирование» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. table.sort с компараторами
  2. table.concat и table.move
  3. Глубокое и поверхностное копирование
  4. Преобразование таблиц: map, filter, reduce
← Назад к Lua Academy