Métaméthodes arithmétiques - Partie 2
Fait partie de la section Logic & Flow du Journey Lua de Coddy — leçon 22 sur 54.
En s'appuyant sur l'addition et la soustraction, vous pouvez également définir le comportement de multiplication et de division pour vos tables en utilisant les métaméthodes __mul et __div. Celles-ci fonctionnent de la même manière que __add et __sub, mais elles répondent aux opérateurs * et /.
La métaméthode __mul est particulièrement utile lorsque vous souhaitez mettre à l'échelle les valeurs d'une table. Par exemple, multiplier un vecteur par un nombre (appelé un scalaire) devrait multiplier chaque composant :
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) -- Résultat : 6 8Remarquez comment la fonction vérifie quel opérande est le nombre et lequel est la table. Cela permet à la fois à vector * 2 et 2 * vector de fonctionner correctement.
La métaméthode __div fonctionne de manière similaire pour la division :
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) -- Résultat : 1.5 2Ces métaméthodes complètent les opérations arithmétiques de base pour vos types personnalisés, vous donnant un contrôle total sur la manière dont les opérateurs mathématiques se comportent avec vos tables.
Défi
FacileÉcrivez une fonction scaleVector qui prend x, y et scalar et retourne le vecteur mis à l'échelle sous forme de chaîne formatée.
Créez une table vectorielle avec les coordonnées données, attachez une métatable avec la métaméthode __mul pour permettre la multiplication scalaire, multipliez le vecteur par le scalaire en utilisant l'opérateur *, et retournez le résultat.
Logique :
- Créez une table vectorielle avec les clés
xetydéfinies sur les coordonnées fournies - Créez une métatable avec
__mulqui gère la multiplication entre un vecteur et un scalaire - La fonction
__muldoit vérifier quel opérande est le nombre et lequel est la table - Retournez une nouvelle table avec
x = vec.x * scalarety = vec.y * scalar - Attachez la métatable à la table vectorielle en utilisant
setmetatable() - Multipliez le vecteur par le scalaire en utilisant
vector * scalar - Retournez le résultat sous forme de chaîne au format
"x y"(les valeurs x et y séparées par un espace)
Paramètres :
x(nombre) : La coordonnée x du vecteury(nombre) : La coordonnée y du vecteurscalar(nombre) : La valeur scalaire par laquelle multiplier le vecteur
Retourne : Le vecteur mis à l'échelle sous forme de chaîne au format "x y" (string)
Aide-mémoire
Les métaméthodes __mul et __div définissent le comportement de multiplication et de division pour les tables, en répondant aux opérateurs * et /.
La métaméthode __mul est utile pour mettre à l'échelle les valeurs d'une table. Lors de la multiplication d'un vecteur par un scalaire, vérifiez quel opérande est le nombre et lequel est la table pour permettre à la fois vector * 2 et 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) -- Résultat : 6 8La métaméthode __div fonctionne de manière similaire pour la division :
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) -- Résultat : 1.5 2Essayez vous-même
function scaleVector(x, y, scalar)
-- Écrire le code ici
end
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Logic & Flow
1Itération avancée des tables
Itérer avec pairs()Itérer avec ipairs()pairs() vs. ipairs()Récapitulatif - Fiche de personnage4Introduction aux Metatables
Qu'est-ce qu'une Metatable ?setmetatable & getmetatableLa métaméthode __indexLa métaméthode __newindexLa métaméthode __tostringMétaméthodes arithmétiques - Partie 1Métaméthodes arithmétiques - Partie 2Récapitulatif - Table en lecture seule2Plus de fonctions de la bibliothèque table
table.concat()Construction de table & unpack()table.sort()Tri personnalisé avec des fonctionsRécapitulatif - Tableau des scores3Concepts avancés sur les fonctions
Retourner plusieurs valeursFonctions variadiques (...)Les fonctions comme valeurs de première classeFonctions anonymesQu'est-ce qu'une closure ?Récapitulatif - Gestionnaire d'événements simple