Comparando Objetos (<, >)
Parte da seção Object Oriented Programming do Journey de Lua da Coddy — lição 29 de 70.
Além de aritmética e concatenação, você também pode definir como os objetos se comparam entre si usando metamétodos de comparação. O metamétodo __lt manipula o operador "menor que" (<code><).
Quando o Lua avalia a < b, ele procura por __lt na metatabela. Este metamétodo deve retornar true ou false com base na sua lógica de comparação.
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
endCom __lt definido, você agora pode comparar itens diretamente:
local apple = Item:new("Apple", 2)
local laptop = Item:new("Laptop", 999)
print(apple < laptop) -- Saída: true
print(laptop < apple) -- Saída: falseAqui está a parte inteligente: Lua deriva automaticamente o operador de __lt. Quando você escreve a > b, Lua simplesmente avalia b < a em vez disso. Portanto, definir apenas __lt oferece ambas as direções de comparação gratuitamente.
Desafio
FácilVamos construir uma classe Product que possa ser comparada usando os operadores <code>< e com base no preço. Isso é perfeito para cenários como ordenar itens em um carrinho de compras ou encontrar a opção mais barata em uma lista.
Você organizará seu código em dois arquivos:
Product.lua: Defina sua classe Product com os camposnameeprice. Inclua um construtor:new(name, price)e implemente o metamétodo__ltpara comparar produtos pelo seu preço. Lembre-se de que definir__ltautomaticamente fornece o operadortambém — o Lua cuida disso para você!main.lua: Importe seu módulo Product, crie instâncias de produtos a partir das entradas e compare-as para determinar qual custa mais ou menos.
Você receberá quatro entradas:
- Nome do primeiro produto
- Preço do primeiro produto
- Nome do segundo produto
- Preço do segundo produto
No seu arquivo principal, crie dois produtos com os nomes e preços fornecidos. Em seguida, realize três comparações e imprima o resultado de cada uma em uma linha separada:
- O primeiro produto é menor que o segundo? (imprima
trueoufalse) - O primeiro produto é maior que o segundo? (imprima
trueoufalse) - Imprima o nome do produto mais barato
Por exemplo, se as entradas forem Apple, 2, Laptop e 999, a saída deve ser:
true
false
AppleA Apple (preço 2) é menor que o Laptop (preço 999), então a primeira comparação é true. A Apple não é maior que o Laptop, então a segunda é false. E como a Apple tem o preço mais baixo, ela é impressa como o produto mais barato.
Folha de consulta
O metamétodo __lt lida com o operador "menor que" (<code><) para objetos personalizados.
Quando o Lua avalia a < b, ele procura por __lt na metatabela. Este metamétodo deve retornar true ou false com base na sua lógica de comparação.
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
endCom o __lt definido, você pode comparar itens diretamente:
local apple = Item:new("Apple", 2)
local laptop = Item:new("Laptop", 999)
print(apple < laptop) -- Saída: true
print(laptop < apple) -- Saída: falseO Lua deriva automaticamente o operador a partir de __lt. Quando você escreve a > b, o Lua avalia b < a em vez disso. Definir apenas __lt fornece ambas as direções de comparação.
Experimente você mesmo
-- Requer o módulo Product
local Product = require('Product')
-- Lê as entradas
local name1 = io.read()
local price1 = tonumber(io.read())
local name2 = io.read()
local price2 = tonumber(io.read())
-- TODO: Cria duas instâncias de Product usando Product:new()
-- TODO: Compara os produtos usando o operador < e imprime true/false
-- TODO: Compara os produtos usando o operador > e imprime true/false
-- TODO: Imprime o nome do produto mais barato
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Object Oriented Programming
1O Conceito 'Self'
Tabelas com Funções'self' ExplícitoA Sintaxe de Dois-pontosPonto vs Dois-pontosRecapitulação - Movendo o Ponto4Projeto: Banco Digital
Configuração do ProjetoMétodo de Depósito7Polimorfismo e Sobrescrita
Sobrescrita de MétodosChamando Métodos da Classe PaiDuck TypingInterface ComumVerificando o TipoRecapitulação - Papéis de Funcionários10Projeto: Gerenciador de Formas
Configuração do ProjetoClasse Retângulo2Padrão de Protótipo de Classe
O Conceito de ProtótipoVinculando com __indexO Construtor :new()Inicializando AtributosInstâncias IndependentesRecapitulação - Fábrica de Carros5Sobrecarga de Operadores em POO
Somando ObjetosSubtraindo ObjetosConcatenando ObjetosComparando Objetos (<, >)Recapitulação - Matemática de Carteira8Encapsulamento
Convenções de NomenclaturaClosures para PrivacidadeAcesso via ClosuresTabelas Somente LeituraLógica de ValidaçãoRecapitulação - Cofre Seguro11Padrões de Projeto (Lite)
Funções FactoryTabela SingletonPadrão IteratorObserver (Listener)Recapitulação - Logger Factory3Estado e Comportamento do Objeto
Variáveis de InstânciaMétodos GetterMétodos SetterPropriedades CalculadasFormatação de StringsVerificações de IgualdadeRecapitulação - Nota do Aluno6Fundamentos de Herança
Configurando a HerançaHerdando MétodosEstendendo o ConstrutorAdicionando Métodos FilhosCompartilhado vs ÚnicoRecapitulação - Hierarquia de Formas