Mettre à jour une valeur dans un HashMap en Rust : du débutant au pro

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Comment mettre à jour une valeur dans un mutable HashMap en Rust : du débutant au pro

\n\n

Avez-vous déjà été confronté à une situation où vous deviez mettre à jour une valeur dans un HashMap en Rust, mais le compilateur refusait obstinément votre code ? Si oui, vous n'êtes pas seul. La question "How can I update a value in a mutable HashMap?" sur Stack Overflow a recueilli des milliers de vues, ce qui signifie que même les développeurs expérimentés se perdent parfois dans les nuances de cette collection.

\n\n

Dans cet article, nous allons analyser toutes les façons de mettre à jour les valeurs dans un HashMap en Rust : du insert de base au entry().and_modify() avancé. Vous apprendrez à modifier correctement les données, à éviter les erreurs typiques et à écrire du code idiomatique. C'est parti !

\n\n

Pourquoi la mise à jour dans un HashMap n'est-elle pas simplement "prendre et changer" ?

\n\n

Contrairement à de nombreux langages, Rust vous oblige à travailler explicitement avec la propriété et l'emprunt. Lorsque vous souhaitez mettre à jour une valeur dans un HashMap, vous devez résoudre trois problèmes :

\n\n
    \n
  • Vérifier l'existence de la clé — cette valeur existe-t-elle déjà ?
  • \n
  • Modifier la valeur — si la clé existe, la mettre à jour
  • \n
  • Insérer une nouvelle — si la clé n'existe pas, l'ajouter
  • \n
\n\n

Cela semble simple ? Regardons le code.

\n\n

Méthode 1 : Insert classique (mais avec un piège)

\n\n

La façon la plus directe est d'utiliser insert. Il écrase la valeur si la clé existe, ou insère une nouvelle paire si la clé n'existe pas.

\n\n
use std::collections::HashMap;\n\nlet mut scores = HashMap::new();\nscores.insert(String::from("Alice"), 10);\nscores.insert(String::from("Bob"), 20);\n\n// Mettre à jour la valeur pour Alice\nscores.insert(String::from("Alice"), 15);\n\nprintln!("{:?}", scores); // {"Alice": 15, "Bob": 20}
\n\n

Ça marche ? Oui. Mais il y a un détail : insert retourne Option<V> — l'ancienne valeur, si elle existait. C'est utile si vous voulez conserver la valeur précédente. Mais que faire si vous devez mettre à jour la valeur en fonction de l'ancienne ? Par exemple, augmenter le score de 1 ?

\n\n
// Nous voulons augmenter le score d'Alice de 1\nif let Some(score) = scores.get_mut("Alice") {\n    *score += 1;\n}
\n\n

Cela fonctionne, mais nécessite deux opérations : vérifier l'existence et modifier. Et si la clé n'existe pas ? Il faudra faire une insertion séparément. Pas très élégant.

\n\n

Méthode 2 : Entry API — le roi des mises à jour

\n\n

Rust dispose d'un outil puissant — l'Entry API. Il permet, en une seule expression, de vérifier l'existence d'une clé, de mettre à jour ou d'insérer une valeur. C'est la façon idiomatique de travailler avec un HashMap.

\n\n
use std::collections::HashMap;\n\nlet mut word_count = HashMap::new();\n\n// Compter les mots dans une phrase\nfor word in "hello world hello Rust".split_whitespace() {\n    let count = word_count.entry(word.to_string()).or_insert(0);\n    *count += 1;\n}\n\nprintln!("{:?}", word_count);\n// {"hello": 2, "world": 1, "Rust": 1}
\n\n

Décortiquons la magie :

\n
    \n
  • entry(key) — crée une entrée pour la clé
  • \n
  • or_insert(0) — si la clé n'existe pas, insère la valeur 0 et retourne une référence mutable sur celle-ci
  • \n
  • *count += 1 — déréférence la référence et augmente la valeur
  • \n
\n\n

Et voilà ! Une seule ligne — et nous avons résolu le problème. Mais ce n'est pas tout.

\n\n

Méthode 3 : and_modify — quand il faut seulement mettre à jour

\n\n

Que faire si vous voulez mettre à jour la valeur uniquement si la clé existe, et si elle n'existe pas, ne rien faire ? Ou insérer une autre valeur ? Pour cela, il y a and_modify et or_insert en chaîne.

\n\n
use std::collections::HashMap;\n\nlet mut inventory = HashMap::new();\ninventory.insert("apples".to_string(), 10);\ninventory.insert("bananas".to_string(), 5);\n\n// Augmenter le nombre de pommes de 1 si elles existent\ninventory.entry("apples".to_string())\n    .and_modify(|

Blogs

Book Recommendations