Metamétodos Aritméticos Parte 1
Parte da seção Logic & Flow do Journey de Lua da Coddy — lição 21 de 54.
Você aprendeu como personalizar o que acontece quando você imprime uma tabela usando __tostring. Agora você descobrirá que as metatables também podem definir o que acontece quando você usa operadores aritméticos como + e - em suas tabelas.
Normalmente, se você tentar somar duas tabelas com o operador +, o Lua retornará um erro porque não sabe como somar tabelas. Mas com metamétodos aritméticos, você pode definir exatamente o que a adição significa para seus tipos de dados personalizados.
O metamétodo __add controla o comportamento da adição. Quando o Lua encontra o operador + entre dois valores e pelo menos um deles possui uma metatabela com __add, ele chama essa função em vez de produzir um erro:
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) -- Saída: 4 6A função __add recebe dois argumentos: o operando da esquerda e o operando da direita. Neste exemplo, ela cria uma nova tabela com valores x e y que são a soma dos valores correspondentes de ambas as tabelas de entrada.
Da mesma forma, o metamétodo __sub controla a subtração com o operador -:
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) -- Saída: 2 2Esta capacidade de definir o comportamento de operadores personalizados é chamada de sobrecarga de operadores.
Desafio
FácilEscreva uma função addVectors que receba x1, y1, x2 e y2 e retorne o resultado da soma de dois vetores.
Crie duas tabelas de vetores com as coordenadas fornecidas, anexe uma metatabela com o metamétodo __add para habilitar a adição de vetores, some-os usando o operador + e retorne o resultado como uma string formatada.
Lógica:
- Crie a primeira tabela de vetor com as chaves
x = x1ey = y1 - Crie a segunda tabela de vetor com as chaves
x = x2ey = y2 - Crie uma metatabela com
__addque receba dois vetores e retorne uma nova tabela comx = a.x + b.xey = a.y + b.y - Anexe a metatabela a ambas as tabelas de vetores usando
setmetatable() - Some os dois vetores usando
v1 + v2 - Retorne o resultado como uma string no formato
"x y"(os valores x e y separados por um espaço)
Parâmetros:
x1(número): A coordenada x do primeiro vetory1(número): A coordenada y do primeiro vetorx2(número): A coordenada x do segundo vetory2(número): A coordenada y do segundo vetor
Retornos: A soma dos dois vetores como uma string no formato "x y" (string)
Folha de consulta
Metatabelas podem definir o que acontece quando você usa operadores aritméticos como + e - em tabelas. Isso é chamado de sobrecarga de operadores.
O metamétodo __add controla o comportamento da adição com o operador +:
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) -- Saída: 4 6A função __add recebe dois argumentos: o operando da esquerda e o operando da direita.
O metamétodo __sub controla a subtração com o operador -:
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) -- Saída: 2 2Experimente você mesmo
function addVectors(x1, y1, x2, y2)
-- Escreva o código aqui
end
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Logic & Flow
1Iteração Avançada de Tabelas
Iterando com pairs()Iterando com ipairs()pairs() vs. ipairs()Revisão - Ficha de Personagem4Introdução às Metatabelas
O que é uma Metatabela?setmetatable & getmetatableO Metamétodo __indexO Metamétodo __newindexO Metamétodo __tostringMetamétodos Aritméticos Parte 1Metamétodos Aritméticos Parte 2Recapitulação - Tabela Somente Leitura2Mais Funções da Biblioteca Table
table.concat()Construção de tabelas e unpack()table.sort()Ordenação personalizada com funçõesRecapitulação - Placar de recordes