Использование функций "Объект" в 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