Menu
Coddy logo textTech

Сравнение объектов (<, >)

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

Помимо арифметики и конкатенации, вы также можете определить, как объекты сравниваются друг с другом, используя метаметоды сравнения. Метаметод __lt обрабатывает оператор «меньше чем» (<code><).

Когда Lua вычисляет a < b, она ищет __lt в метатаблице. Этот метаметод должен возвращать true или false на основе вашей логики сравнения.

local Item = {}
Item.__index = Item

function Item:new(name, price)
    local obj = {name = name, price = price}
    setmetatable(obj, Item)
    return obj
end

function Item.__lt(a, b)
    return a.price < b.price
end

С определенным __lt теперь вы можете сравнивать предметы напрямую:

local apple = Item:new("Apple", 2)
local laptop = Item:new("Laptop", 999)

print(apple < laptop)   -- Результат: true
print(laptop < apple)   -- Результат: false

Вот в чем хитрость: Lua автоматически выводит оператор из __lt. Когда вы пишете a > b, Lua просто вычисляет b < a вместо этого. Таким образом, определение только __lt дает вам оба направления сравнения бесплатно.

challenge icon

Задание

Легко

Давайте создадим класс Product, который можно сравнивать с помощью операторов <code>< и на основе цены. Это идеально подходит для таких сценариев, как сортировка товаров в корзине или поиск самого дешевого варианта в списке.

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

  • Product.lua: Определите класс Product с полями name и price. Включите конструктор :new(name, price) и реализуйте метаметод __lt для сравнения продуктов по их цене. Помните, что определение __lt автоматически дает вам и оператор — Lua берет это на себя!
  • main.lua: Подключите модуль Product, создайте экземпляры продуктов из входных данных и сравните их, чтобы определить, какой из них стоит больше или меньше.

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

  1. Название первого продукта
  2. Цена первого продукта
  3. Название второго продукта
  4. Цена второго продукта

В вашем основном файле создайте два продукта с заданными именами и ценами. Затем выполните три сравнения и выведите результат каждого на отдельной строке:

  1. Первый продукт меньше второго? (выведите true или false)
  2. Первый продукт больше второго? (выведите true или false)
  3. Выведите название более дешевого продукта

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

true
false
Apple

Apple (цена 2) меньше, чем Laptop (цена 999), поэтому первое сравнение — true. Apple не больше, чем Laptop, поэтому второе — false. И так как у Apple цена ниже, оно выводится как более дешевый продукт.

Шпаргалка

Метаметод __lt обрабатывает оператор «меньше» (<code><) для пользовательских объектов.

Когда Lua вычисляет a < b, она ищет __lt в метатаблице. Этот метаметод должен возвращать true или false в зависимости от вашей логики сравнения.

local Item = {}
Item.__index = Item

function Item:new(name, price)
    local obj = {name = name, price = price}
    setmetatable(obj, Item)
    return obj
end

function Item.__lt(a, b)
    return a.price < b.price
end

С определенным __lt вы можете сравнивать объекты напрямую:

local apple = Item:new("Apple", 2)
local laptop = Item:new("Laptop", 999)

print(apple < laptop)   -- Результат: true
print(laptop < apple)   -- Результат: false

Lua автоматически выводит оператор из __lt. Когда вы пишете a > b, Lua вместо этого вычисляет b < a. Определение только __lt дает вам оба направления сравнения.

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

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

-- Прочитать входные данные
local name1 = io.read()
local price1 = tonumber(io.read())
local name2 = io.read()
local price2 = tonumber(io.read())

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

-- TODO: Сравнить продукты, используя оператор <, и вывести true/false

-- TODO: Сравнить продукты, используя оператор >, и вывести true/false

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

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

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