Menu
Coddy logo textTech

Сложение объектов

Часть раздела Object Oriented Programming путешествия по Lua на Coddy — урок 26 из 70.

Вы уже видели, как такие метаметоды, как __tostring и __eq, позволяют настраивать поведение объектов. Теперь мы распространим это на арифметические операции, начиная со сложения.

Метаметод __add определяет, что происходит при использовании оператора + между двумя объектами. Когда Lua видит a + b, она ищет __add в метатаблице любого из операндов.

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    local obj = {x = x, y = y}
    setmetatable(obj, Vector)
    return obj
end

function Vector.__add(v1, v2)
    return Vector:new(v1.x + v2.x, v1.y + v2.y)
end

Обратите внимание, что __add определяется через точку, а не через двоеточие. Она получает оба операнда в качестве аргументов и должна возвращать новый объект, а не изменять исходные. Это делает операцию предсказуемой и безопасной.

local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b

print(c.x, c.y)  -- Вывод: 4  6

Ключевой момент заключается в том, что __add должен находиться в самой метатаблице (в данном случае Vector), а не просто в объекте. Поскольку мы устанавливаем Vector в качестве метатаблицы для всех экземпляров, все они автоматически разделяют это поведение.

challenge icon

Задание

Легко

Давайте создадим класс Vector, который поддерживает сложение с помощью оператора +. Это ваш первый шаг в перегрузку операторов — создание объектов, которые естественным образом работают со встроенными операторами Lua.

Вы организуете свой код в двух файлах:

  • Vector.lua: Определите класс Vector с компонентами x и y. Включите конструктор :new(x, y) и реализуйте метаметод __add, чтобы сложение двух векторов создавало новый вектор с комбинированными компонентами. Помните, что __add использует синтаксис с точкой (не с двоеточием) и получает оба операнда в качестве аргументов.
  • main.lua: Подключите модуль Vector, создайте экземпляры векторов и продемонстрируйте, что их сложение дает правильный результат.

Вы получите четыре входных значения:

  1. Компонента x первого вектора
  2. Компонента y первого вектора
  3. Компонента x второго вектора
  4. Компонента y второго вектора

В основном файле создайте два вектора с заданными компонентами, сложите их с помощью оператора + и выведите значения x и y результирующего вектора на отдельных строках.

Например, если входные данные — 3, 4, 1, 2, вывод должен быть следующим:

4
6

Первый вектор (3, 4) плюс второй вектор (1, 2) дают в сумме новый вектор (4, 6).

Шпаргалка

Метаметод __add определяет, что происходит при использовании оператора + между двумя объектами.

Когда Lua видит a + b, она ищет __add в метатаблице любого из операндов.

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    local obj = {x = x, y = y}
    setmetatable(obj, Vector)
    return obj
end

function Vector.__add(v1, v2)
    return Vector:new(v1.x + v2.x, v1.y + v2.y)
end

__add определяется через точку, а не через двоеточие. Он получает оба операнда в качестве аргументов и должен возвращать новый объект, а не изменять исходные.

local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b

print(c.x, c.y)  -- Вывод: 4  6

__add должен находиться в самой метатаблице, а не просто в объекте.

Попробуйте сами

-- Подключите модуль Vector
local Vector = require('Vector')

-- Считайте входные данные
local x1 = tonumber(io.read())
local y1 = tonumber(io.read())
local x2 = tonumber(io.read())
local y2 = tonumber(io.read())

-- TODO: Создайте два экземпляра Vector, используя введенные значения

-- TODO: Сложите два вектора, используя оператор +

-- TODO: Выведите значения x и y результирующего вектора на отдельных строках
quiz iconПроверьте себя

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

Все уроки раздела Object Oriented Programming