Menu
Coddy logo textTech

Арифметические метаметоды. Часть 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

Эта возможность определять пользовательское поведение операторов называется перегрузкой операторов.

challenge icon

Задание

Легко

Напишите функцию 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
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Logic & Flow