Introduction
Des variables distinctes conviennent aux exemples très simples, mais les programmes réels doivent souvent regrouper des données liées dans une même valeur. Une structure Rust définit la forme de cet enregistrement, tandis qu’un bloc impl lui ajoute les opérations qui lui sont associées.
Vous allez compléter un modèle InventoryItem préparé à l’aide de quatre petites modifications : définir ses champs, construire un article valide, calculer la valeur du stock avec &self, puis mettre à jour sa quantité avec &mut self. Le programme final vérifiera à la fois l’état enregistré et le comportement des méthodes.
Définir l’enregistrement d’inventaire
Dans cette étape, vous allez définir les trois données qui appartiennent à un même article d’inventaire.
Accédez au projet Cargo préparé et ouvrez son fichier source :
cd /home/labex/project/inventory-item
nano src/main.rs
La déclaration struct InventoryItem { ... } introduit un nouveau type d’enregistrement. Entre les accolades, chaque champ possède un nom suivi de deux-points et de son type. Chaque valeur InventoryItem doit fournir tous ces champs.
Remplacez le commentaire de l’étape 1 par ces trois lignes de champs :
name: String,
price_cents: u32,
quantity: u32,
name possède le texte, tandis que les deux champs u32 stockent des nombres entiers non négatifs. Les virgules finales séparent les champs et facilitent l’ajout ou la réorganisation des lignes ultérieurement.
Enregistrez avec Ctrl+O, appuyez sur Entrée, puis quittez avec Ctrl+X. Demandez à Cargo de vérifier les définitions de types :
cargo check
Un résultat Finished sans avertissement signifie que la structure est valide et que chaque valeur préparée est correctement utilisée. Le constructeur contient encore todo!, un marqueur temporaire indiquant qu’une partie du code n’est pas terminée. Rust l’autorise pendant cargo check, mais l’exécution d’un chemin qui atteint todo! provoquerait une panique. Vous le remplacerez avant d’exécuter le programme à l’étape suivante.
Construire un article complet
Dans cette étape, vous allez transformer la fonction associée new en constructeur qui renvoie un InventoryItem complet.
Le bloc impl InventoryItem regroupe les opérations liées à ce type. new est une fonction associée, car elle ne reçoit pas self ; elle est appelée via le type avec InventoryItem::new(...). Une méthode telle que value_cents reçoit self et est appelée via une valeur avec item.value_cents(). Le type de retour Self est un autre nom pour InventoryItem à l’intérieur de ce bloc impl.
Ouvrez le fichier source :
nano src/main.rs
Dans new, remplacez entièrement la ligne todo!(...) par :
Self { name, price_cents, quantity }
Il s’agit d’une expression de structure. La syntaxe abrégée des champs de Rust permet à name de signifier name: name lorsque le paramètre et le champ portent le même nom. L’expression ne comporte pas de point-virgule, car elle représente la valeur renvoyée par la fonction.
Enregistrez et quittez, puis vérifiez et exécutez le programme :
cargo check
cargo run --quiet
La sortie actuelle doit être :
Preparing Notebook at 250 cents with 4 units
Item: Notebook
Unit price: 250 cents
Starting value: 0 cents
Adding 3 units
Quantity after restock: 4
Final value: 0 cents
L’article existe maintenant avec les valeurs de champs fournies. Les zéros et la quantité inchangée proviennent des deux autres emplacements réservés dans les méthodes ; ils sont donc attendus à ce stade.
Calculer la valeur avec &self
Dans cette étape, vous allez terminer une méthode qui lit deux champs sans prendre possession de l’article ni le modifier.
Le paramètre &self est une référence partagée vers le InventoryItem actuel. Il s’agit d’une forme abrégée pour une valeur empruntée dont le type concret est &InventoryItem. La méthode le reçoit automatiquement lorsque vous appelez item.value_cents().
Ouvrez le fichier source :
nano src/main.rs
Dans value_cents, remplacez uniquement l’emplacement réservé 0 par :
self.price_cents * self.quantity
Le point permet de sélectionner des champs de l’article emprunté. La multiplication produit la valeur totale en centimes, et l’expression devient la valeur u32 renvoyée par la méthode, car elle ne se termine pas par un point-virgule.
Enregistrez et quittez, puis exécutez :
cargo run --quiet
Les lignes concernant la valeur doivent maintenant être :
Starting value: 1000 cents
...
Final value: 1000 cents
Quatre unités à 250 centimes valent 1000 centimes. Les deux lignes correspondent encore, car restock n’a pas encore modifié la quantité ; cette modification contrôlée constitue la dernière étape.
Réapprovisionner avec &mut self
Dans cette étape, vous allez terminer une méthode qui modifie un champ grâce à un emprunt exclusif.
Le récepteur &mut self est une référence mutable vers l’article actuel. Il permet à la méthode de mettre à jour des champs sans en prendre possession. La liaison dans main est déjà déclarée avec let mut item, ce qui lui permet de fournir temporairement cet accès mutable.
Ouvrez le fichier source :
nano src/main.rs
Remplacez le commentaire de l’étape 4 dans restock par :
self.quantity += amount;
L’opérateur += ajoute la valeur située à droite au champ existant, puis enregistre le résultat dans ce même champ. Il s’agit d’une instruction, qui se termine donc par un point-virgule.
Enregistrez et quittez, puis vérifiez et exécutez le modèle terminé :
cargo check
cargo run --quiet
La sortie complète doit être :
Preparing Notebook at 250 cents with 4 units
Item: Notebook
Unit price: 250 cents
Starting value: 1000 cents
Adding 3 units
Quantity after restock: 7
Final value: 1750 cents
La quantité passe de quatre à sept, et la même méthode value_cents observe le nouvel état. L’emprunt mutable se termine après restock, ce qui permet au code suivant de lire normalement l’article.
Résumé
Vous avez défini une structure qui regroupe des champs liés, construit des valeurs avec un constructeur Self, lu l’état avec une méthode &self et mis à jour l’état avec une méthode &mut self. La sortie finale de l’inventaire a confirmé que la construction, le calcul et la modification fonctionnent ensemble.


