Арифметические метаметоды. Часть 1
Часть раздела Logic & Flow путешествия по Lua на Coddy — урок 21 из 54.
Вы узнали, как настраивать поведение при выводе таблицы на печать с помощью __tostring. Теперь вы узнаете, что метатаблицы также могут определять, что происходит при использовании арифметических операторов, таких как + и -, с вашими таблицами.
Обычно, если вы попытаетесь сложить две таблицы с помощью оператора +, Lua выдаст ошибку, потому что она не знает, как складывать таблицы. Но с помощью арифметических метаметодов вы можете точно определить, что означает сложение для ваших пользовательских типов данных.
Метаметод __add управляет поведением сложения. Когда Lua встречает оператор + между двумя значениями, и хотя бы у одного из них есть метатаблица с полем __add, она вызывает эту функцию вместо того, чтобы выдать ошибку:
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- Вывод: 4 6Функция __add принимает два аргумента: левый операнд и правый операнд. В этом примере она создает новую таблицу со значениями x и y, которые являются суммой соответствующих значений из обеих входных таблиц.
Аналогично, метаметод __sub управляет вычитанием с помощью оператора -:
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- Вывод: 2 2Эта возможность определять пользовательское поведение операторов называется перегрузкой операторов.
Задание
ЛегкоНапишите функцию addVectors, которая принимает x1, y1, x2 и y2 и возвращает результат сложения двух векторов.
Создайте две таблицы векторов с заданными координатами, прикрепите метатаблицу с метаметодом __add для включения сложения векторов, сложите их с помощью оператора + и верните результат в виде отформатированной строки.
Логика:
- Создайте первую таблицу вектора с ключами
x = x1иy = y1 - Создайте вторую таблицу вектора с ключами
x = x2иy = y2 - Создайте метатаблицу с
__add, которая принимает два вектора и возвращает новую таблицу сx = a.x + b.xиy = a.y + b.y - Прикрепите метатаблицу к обеим таблицам векторов с помощью
setmetatable() - Сложите два вектора, используя
v1 + v2 - Верните результат в виде строки в формате
"x y"(значения x и y, разделенные пробелом)
Параметры:
x1(number): Координата x первого вектораy1(number): Координата y первого вектораx2(number): Координата x второго вектораy2(number): Координата y второго вектора
Возвращает: Сумма двух векторов в виде строки в формате "x y" (string)
Шпаргалка
Метатаблицы могут определять, что происходит при использовании арифметических операторов, таких как + и -, с таблицами. Это называется перегрузкой операторов.
Метаметод __add управляет поведением сложения с оператором +:
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- Output: 4 6Функция __add получает два аргумента: левый операнд и правый операнд.
Метаметод __sub управляет вычитанием с оператором -:
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- Output: 2 2Попробуйте сами
function addVectors(x1, y1, x2, y2)
-- Напишите код здесь
end
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Logic & Flow
1Продвинутая итерация таблиц
Итерация с помощью pairs()Итерация с помощью ipairs()pairs() против ipairs()Повторение — Лист персонажа4Введение в метатаблицы
Что такое метатаблица?setmetatable и getmetatableМетаметод __indexМетаметод __newindexМетаметод __tostringАрифметические метаметоды. Часть 1Арифметические метаметоды. Часть 2Итоги — Таблица только для чтения2Дополнительные функции библиотеки table
table.concat()Создание таблиц и unpack()table.sort()Пользовательская сортировка с помощью функцийИтоги — Таблица рекордов