0Pricing
Lua Academy · Урок

Финализаторы с __gc

Регистрируйте метаметоды __gc для очистки при сборе объектов.

«Финализаторы с __gc» — бесплатный урок Lua Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.

Что такое финализатор?

Финализатор — это функция, вызываемая сборщиком мусора непосредственно перед освобождением объекта. В Lua он реализуется с помощью метаметода __gc в метатаблице таблицы.

Установка финализатора

Добавьте функцию __gc в метатаблицу до создания объекта или во время его создания.

local mt = {
  __gc = function(self)
    print("Finalizing:", self.name)
  end
}
do
  local obj = setmetatable({name = "resource"}, mt)
end
collectgarbage()  -- prints: Finalizing: resource

Шаблон очистки ресурсов

Финализаторы идеально подходят для освобождения внешних ресурсов: дескрипторов файлов, соединений с базой данных или памяти C.

local function openResource(path)
  local f = io.open(path, "r")
  return setmetatable({handle = f, path = path}, {
    __gc = function(self)
      if self.handle then
        self.handle:close()
        print("Closed:", self.path)
      end
    end
  })
end

Порядок работы финализаторов

Объекты с финализаторами удаляются в обратном порядке создания. По умолчанию за один цикл сборки мусора выполняется один финализатор.

Воскрешение

Если финализатор сохраняет ссылку на объект (в глобальной переменной или внешней локальной переменной), объект воскресает. При окончательном удалении для него будет выполнен ещё только один вызов финализатора.

Пользовательские данные и __gc

В расширениях на C метаметод __gc для пользовательских данных — основной способ освободить память C. В чистом Lua таблицы используют тот же механизм через метатаблицы.

Объекты-прокси для RAII

Создайте таблицу-прокси, чей __gc закрывает настоящий ресурс. Это имитирует RAII из C++.

local function scoped(resource, cleanup)
  return setmetatable({resource}, {
    __gc = function(self) cleanup(self[1]) end
  })
end

Ограничения финализаторов

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

Слабые таблицы и финализаторы

Объекты в слабых таблицах всё равно могут быть финализированы. После финализации (и возможного воскрешения) они полностью удаляются во время следующего цикла.

Защита финализатора toLua

Используйте внутри финализатора логический флаг, чтобы предотвратить повторную очистку в случае воскрешения объекта.

local mt = {}
mt.__gc = function(self)
  if not self._closed then
    self._closed = true
    -- cleanup...
  end
end

Практические рекомендации

Для детерминированной очистки предпочитайте явные методы :close() или :destroy(). Используйте __gc как страховку от случайно пропущенной очистки, а не как основной способ управления ресурсами.

Вопрос о финализаторах

Когда вызывается метаметод __gc?

Итоги: финализаторы с __gc

Метаметод __gc выполняется непосредственно перед удалением объекта, обеспечивая очистку ресурсов в стиле RAII. Используйте его как страховку; для детерминированного управления ресурсами предпочитайте явные методы закрытия и уничтожения.

Часто задаваемые вопросы

Урок «Финализаторы с __gc» бесплатный?

Да — полный текст урока «Финализаторы с __gc» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.

Чему я научусь в уроке «Финализаторы с __gc»?

Регистрируйте метаметоды __gc для очистки при сборе объектов. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Lua Academy?

Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Финализаторы с __gc»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Lua Academy?

Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

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

  1. Основы сборщика мусора Lua
  2. Слабые ключи и слабые значения
  3. Финализаторы с __gc
  4. Предотвращение утечек памяти
← Назад к Lua Academy