Metamétodos Aritméticos Parte 2
Parte da seção Logic & Flow do Journey de Lua da Coddy — lição 22 de 54.
Baseando-se na adição e subtração, você também pode definir o comportamento de multiplicação e divisão para suas tabelas usando os metamétodos __mul e __div. Estes funcionam da mesma forma que __add e __sub, mas eles respondem aos operadores * e /.
O metamétodo __mul é particularmente útil quando você deseja redimensionar os valores de uma tabela. Por exemplo, multiplicar um vetor por um número (chamado de escalar) deve multiplicar cada componente:
local vector = {x = 3, y = 4}
local meta = {
__mul = function(a, b)
local scalar = type(a) == "number" and a or b
local vec = type(a) == "table" and a or b
return {x = vec.x * scalar, y = vec.y * scalar}
end
}
setmetatable(vector, meta)
local scaled = vector * 2
print(scaled.x, scaled.y) -- Saída: 6 8Observe como a função verifica qual operando é o número e qual é a tabela. Isso permite que tanto vector * 2 quanto 2 * vector funcionem corretamente.
O metamétodo __div funciona de forma semelhante para a divisão:
local meta = {
__div = function(a, b)
return {x = a.x / b, y = a.y / b}
end
}
setmetatable(vector, meta)
local divided = vector / 2
print(divided.x, divided.y) -- Saída: 1.5 2Estes metamétodos completam as operações aritméticas básicas para seus tipos personalizados, oferecendo a você controle total sobre como os operadores matemáticos se comportam com suas tabelas.
Desafio
FácilEscreva uma função scaleVector que receba x, y e scalar e retorne o vetor escalonado como uma string formatada.
Crie uma tabela de vetor com as coordenadas fornecidas, anexe uma metatabela com o metamétodo __mul para permitir a multiplicação escalar, multiplique o vetor pelo escalar usando o operador * e retorne o resultado.
Lógica:
- Crie uma tabela de vetor com as chaves
xeydefinidas para as coordenadas fornecidas - Crie uma metatabela com
__mulque lide com a multiplicação entre um vetor e um escalar - A função
__muldeve verificar qual operando é o número e qual é a tabela - Retorne uma nova tabela com
x = vec.x * scalarey = vec.y * scalar - Anexe a metatabela à tabela do vetor usando
setmetatable() - Multiplique o vetor pelo escalar usando
vector * scalar - Retorne o resultado como uma string no formato
"x y"(os valores x e y separados por um espaço)
Parâmetros:
x(number): A coordenada x do vetory(number): A coordenada y do vetorscalar(number): O valor escalar pelo qual multiplicar o vetor
Retornos: O vetor escalonado como uma string no formato "x y" (string)
Folha de consulta
Os metamétodos __mul e __div definem o comportamento de multiplicação e divisão para tabelas, respondendo aos operadores * e /.
O metamétodo __mul é útil para redimensionar valores de tabelas. Ao multiplicar um vetor por um escalar, verifique qual operando é o número e qual é a tabela para permitir tanto vector * 2 quanto 2 * vector:
local vector = {x = 3, y = 4}
local meta = {
__mul = function(a, b)
local scalar = type(a) == "number" and a or b
local vec = type(a) == "table" and a or b
return {x = vec.x * scalar, y = vec.y * scalar}
end
}
setmetatable(vector, meta)
local scaled = vector * 2
print(scaled.x, scaled.y) -- Output: 6 8O metamétodo __div funciona de forma semelhante para a divisão:
local meta = {
__div = function(a, b)
return {x = a.x / b, y = a.y / b}
end
}
setmetatable(vector, meta)
local divided = vector / 2
print(divided.x, divided.y) -- Output: 1.5 2Experimente você mesmo
function scaleVector(x, y, scalar)
-- 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