Использование функций "Объект" в Lua?

Я хочу иметь возможность иметь "объекты" с определенными функциями, которые ссылаются на себя (я понятия не имею, как это назвать) в Lua. Я видел код того, что я пытаюсь сделать, но я никогда не понимал, что это на самом деле означает. Я попытался просмотреть сайт Lua, но не повезло.

Основной код:

table = {}

function newTable(...)
  ...
  return setmetatable(table)
end

function table:funcName(...)
  ...
end

Может кто-нибудь объяснить, что здесь происходит и как я могу это использовать, пожалуйста? Спасибо за прочтение!

1 ответ

Решение

Отсутствует уже упомянутый один ресурс, который объясняет, как это работает. Вы также можете ознакомиться с разделом ООП lua wiki для более подробного объяснения и примеров.

Кратко изложу ваш пример, начиная с того, как его использовать. Обратите внимание, что я изменил некоторые имена, чтобы они не влияли на стандартные модули, поставляемые с lua. Вы создаете новый объект, вызывая newObject, Вы можете вызывать методы этого объекта, используя : сопровождаемый именем метода:

-- create two instances
object1 = newObject()
object2 = newObject()

-- call 'my_function' method for object1
object1:my_function()

Вам нужно немного узнать о метатаблицах, чтобы понять, как этот механизм работает за кулисами. Когда вы выполняете вызов, как:

object1:my_function()

Это просто синтаксис сахара для:

object1.my_function(object1)

Это может быть разбито на:

object1["my_function"](object1)

Сейчас object1 это просто пустая таблица, возвращаемая newObject - у него нет "my_function" ключ. Обычно это приводит к ошибке, потому что вы пытаетесь вызвать nil значение. Однако вы можете изменить это поведение, используя метатаблицы. Основная идея состоит в том, чтобы настроить __index метаметод, указывающий на таблицу, которая содержит методы вашего класса:

object_table = {}
object_table.__index = object_table
function newObject(...)
  return setmetatable({}, object_table)
end

Процесс поиска метода будет выглядеть следующим образом: object1 -> table, Если object1 не имеет ключа, table консультируется следующий. Если table имеет этот ключ, соответствующее значение возвращается. Если table тогда его тоже нет nil возвращается с table не имеет метатабельных

С помощью этой настройки вы можете "переопределить" метод для конкретного экземпляра объекта, просто назначив имя метода и функцию в качестве пары ключ-значение для этого объекта.

object2.my_function = function (...)
  -- do something different
end
Другие вопросы по тегам