Menu
Coddy logo textTech

Проверка на равенство

Часть раздела Объектно-ориентированное программирование путешествия по Lua на Coddy. Урок 17 из 70.

Вы уже видели, как __tostring управляет отображением объекта. Ещё один полезный метаметод — __eq, который определяет, когда два объекта следует считать равными с помощью оператора ==.

По умолчанию сравнение двух таблиц с помощью == проверяет, является ли это одна и та же таблица в памяти. Два отдельных объекта с идентичными данными вернут значение false:

local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2)  -- Вывод: false (разные таблицы)

С помощью __eq можно определить собственную логику равенства. В классе его добавляют так же, как __tostring, в виде функции в таблице класса. Чтобы равенство работало, оба объекта должны использовать одну и ту же метатаблицу:

local User = {}
User.__index = User

function User:new(id, name)
    local instance = {}
    setmetatable(instance, self)
    instance.id = id
    instance.name = name
    return instance
end

function User:__eq(other)
    return self.id == other.id
end

Теперь два объекта User считаются equal, если у них одинаковый ID, независимо от других полей:

local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")

print(u1 == u2)  -- Вывод: true (тот же ID)
print(u1 == u3)  -- Вывод: false (разные ID)

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

challenge icon

Задание

Легко

Давайте создадим класс Product, который может определить, являются ли два продукта одним и тем же товаром, даже если они хранятся в совершенно разных таблицах! В розничных системах продукты часто имеют уникальные коды SKU (Stock Keeping Units), и два продукта следует считать равными, если у них один и тот же SKU, независимо от других деталей, таких как изменения цены.

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

  • Product.lua: Определите свой класс Product со стандартным шаблоном prototype. Каждый продукт должен хранить sku (уникальный идентификатор) и name. Implement метаметод __eq, чтобы два продукта считались равными, если у них один и тот же SKU: имя не имеет значения для равенства.
  • main.lua: Подключите свой модуль Product и создайте несколько экземпляров продукта. Сравните их с помощью оператора ==, чтобы увидеть свой пользовательский механизм сравнения на практике.

Ваш класс Product должен включать:

  • Конструктор :new(sku, name)
  • Метод :getInfo(), который возвращает строку в формате: [sku]: [name]
  • Метаметод __eq, сравнивающий продукты по их SKU

Вы получите шесть входных значений:

  1. SKU первого продукта
  2. Имя первого продукта
  3. SKU второго продукта
  4. Имя второго продукта
  5. SKU третьего продукта
  6. Имя третьего продукта

В основном файле создайте три продукта, используя предоставленные входные значения, а затем выведите:

  1. Информацию о каждом продукте (три строки)
  2. result сравнения продукта 1 с продуктом 2
  3. result сравнения продукта 1 с продуктом 3

Например, если входными значениями являются ABC123, Wireless Mouse, ABC123, Mouse (Updated), XYZ789 и Keyboard, вывод должен быть таким:

ABC123: Wireless Mouse
ABC123: Mouse (Updated)
XYZ789: Keyboard
true
false

Обратите внимание, что первые два продукта равны (одинаковый SKU), хотя их имена различаются. Именно так реальные системы управления запасами отслеживают продукты при изменениях и обновлениях названий!

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

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

-- Считать входные данные
local sku1 = io.read()
local name1 = io.read()
local sku2 = io.read()
local name2 = io.read()
local sku3 = io.read()
local name3 = io.read()

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

-- TODO: Вывести информацию о каждом продукте (три строки)

-- TODO: Вывести результат сравнения продукта 1 с продуктом 2

-- TODO: Вывести результат сравнения продукта 1 с продуктом 3
quiz iconПроверьте себя

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

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Lua