Метатабельная таблица — это таблица, которая помогает изменить поведение таблицы, к которой она присоединена, с помощью набора ключей и связанных мета-методов. Эти мета-методы являются мощной функциональностью Lua, которая включает такие функции, как —
-
Изменение / добавление функций к операторам на таблицах.
-
Поиск метатаблиц, когда ключ недоступен в таблице, с помощью __index в метатаблице.
Изменение / добавление функций к операторам на таблицах.
Поиск метатаблиц, когда ключ недоступен в таблице, с помощью __index в метатаблице.
Есть два важных метода, которые используются в обработке метатаблиц, которые включают в себя:
-
setmetatable (table, metatable) — этот метод используется для установки метатаблицы для таблицы.
-
getmetatable (table) — этот метод используется для получения метатаблицы таблицы.
setmetatable (table, metatable) — этот метод используется для установки метатаблицы для таблицы.
getmetatable (table) — этот метод используется для получения метатаблицы таблицы.
Давайте сначала посмотрим, как установить одну таблицу как метатабельную к другой. Это показано ниже.
mytable = {} mymetatable = {} setmetatable(mytable,mymetatable)
Приведенный выше код может быть представлен в одной строке, как показано ниже.
mytable = setmetatable({},{})
_индекс
Простой пример метатаблицы для поиска мета-таблицы, когда она недоступна в таблице, показан ниже.
mytable = setmetatable({key1 = "value1"}, { __index = function(mytable, key) if key == "key2" then return "metatablevalue" else return mytable[key] end end }) print(mytable.key1,mytable.key2)
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
value1 metatablevalue
Давайте объясним, что произошло в приведенном выше примере, по шагам.
-
Таблица mytable здесь {key1 = «value1»} .
-
Metatable устанавливается для mytable, который содержит функцию для __index, которую мы называем метаметодом.
-
Метаметод выполняет простую работу по поиску индекса «key2», если он найден, он возвращает «metatablevalue», в противном случае возвращает значение mytable для соответствующего индекса.
Таблица mytable здесь {key1 = «value1»} .
Metatable устанавливается для mytable, который содержит функцию для __index, которую мы называем метаметодом.
Метаметод выполняет простую работу по поиску индекса «key2», если он найден, он возвращает «metatablevalue», в противном случае возвращает значение mytable для соответствующего индекса.
У нас может быть упрощенная версия вышеуказанной программы, как показано ниже.
mytable = setmetatable({key1 = "value1"}, { __index = { key2 = "metatablevalue" } }) print(mytable.key1,mytable.key2)
__newindex
Когда мы добавляем __newindex в metatable, если ключи не доступны в таблице, поведение новых ключей будет определяться мета-методами. Простой пример, когда индекс метатаблицы устанавливается, когда индекс не доступен в основной таблице, приведен ниже.
mymetatable = {} mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable }) print(mytable.key1) mytable.newkey = "new value 2" print(mytable.newkey,mymetatable.newkey) mytable.key1 = "new value 1" print(mytable.key1,mymetatable.newkey1)
Когда вы запускаете вышеуказанную программу, вы получаете следующий вывод.
value1 nil new value 2 new value 1 nil
Вы можете видеть в приведенной выше программе, если ключ существует в основной таблице, он просто обновляет его. Когда ключ недоступен в maintable, он добавляет этот ключ в метатаблицу.
Другой пример, который обновляет ту же таблицу с помощью функции rawset, показан ниже.
mytable = setmetatable({key1 = "value1"}, { __newindex = function(mytable, key, value) rawset(mytable, key, "\""..value.."\"") end }) mytable.key1 = "new value" mytable.key2 = 4 print(mytable.key1,mytable.key2)
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
new value "4"
rawset устанавливает значение без использования __newindex для metatable. Точно так же есть rawget, который получает значение без использования __index.
Добавление поведения оператора в таблицы
Простой пример объединения двух таблиц с помощью оператора + показан ниже —
mytable = setmetatable({ 1, 2, 3 }, { __add = function(mytable, newtable) for i = 1, table.maxn(newtable) do table.insert(mytable, table.maxn(mytable)+1,newtable[i]) end return mytable end }) secondtable = {4,5,6} mytable = mytable + secondtable for k,v in ipairs(mytable) do print(k,v) end
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
1 1 2 2 3 3 4 4 5 5 6 6
Ключ __add включен в metatable для добавления поведения оператора +. Таблица ключей и соответствующего оператора показана ниже.
Sr.No. | Режим и описание |
---|---|
1 |
__добавлять Изменяет поведение оператора ‘+’. |
2 |
__sub Изменяет поведение оператора ‘-‘. |
3 |
__mul Изменяет поведение оператора ‘*’. |
4 |
__div Изменяет поведение оператора ‘/’. |
5 |
__mod Изменяет поведение оператора «%». |
6 |
__unm Изменяет поведение оператора ‘-‘. |
7 |
__concat Изменяет поведение оператора ‘..’. |
8 |
__eq Изменяет поведение оператора ‘==’. |
9 |
__lt Изменяет поведение оператора ‘<‘. |
10 |
__le Изменяет поведение оператора ‘<=’. |
__добавлять
Изменяет поведение оператора ‘+’.
__sub
Изменяет поведение оператора ‘-‘.
__mul
Изменяет поведение оператора ‘*’.
__div
Изменяет поведение оператора ‘/’.
__mod
Изменяет поведение оператора «%».
__unm
Изменяет поведение оператора ‘-‘.
__concat
Изменяет поведение оператора ‘..’.
__eq
Изменяет поведение оператора ‘==’.
__lt
Изменяет поведение оператора ‘<‘.
__le
Изменяет поведение оператора ‘<=’.
__вызов
Добавление поведения вызова метода выполняется с помощью оператора __call. Простой пример, который возвращает сумму значений в основной таблице с переданной таблицей.
mytable = setmetatable({10}, { __call = function(mytable, newtable) sum = 0 for i = 1, table.maxn(mytable) do sum = sum + mytable[i] end for i = 1, table.maxn(newtable) do sum = sum + newtable[i] end return sum end }) newtable = {10,20,30} print(mytable(newtable))
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
70
__нанизывать
Чтобы изменить поведение оператора print, мы можем использовать метаметод __tostring. Простой пример показан ниже.
mytable = setmetatable({ 10, 20, 30 }, { __tostring = function(mytable) sum = 0 for k, v in pairs(mytable) do sum = sum + v end return "The sum of values in the table is " .. sum end }) print(mytable)
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
The sum of values in the table is 60
Если вы полностью знакомы с возможностями мета-таблицы, вы действительно можете выполнить множество операций, которые были бы очень сложными без ее использования. Поэтому постарайтесь больше работать над использованием метатаблиц с различными опциями, доступными в мета таблицах, как описано в примерах, а также создавайте свои собственные образцы.