web-dev-qa-db-fra.com

Comment puis-je mettre à jour une valeur dans un HashMap mutable?

Voici ce que j'essaie de faire:

use std::collections::HashMap;

fn main() {
    let mut my_map = HashMap::new();
    my_map.insert("a", 1);
    my_map.insert("b", 3);

    my_map["a"] += 10;
    // I expect my_map becomes {"b": 3, "a": 11}
}

Mais cela soulève une erreur:

Rust 2015

error[E0594]: cannot assign to immutable indexed content
 --> src/main.rs:8:5
  |
8 |     my_map["a"] += 10;
  |     ^^^^^^^^^^^^^^^^^ cannot borrow as mutable
  |
  = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<&str, i32>`

Rouille 2018

error[E0594]: cannot assign to data in a `&` reference
 --> src/main.rs:8:5
  |
8 |     my_map["a"] += 10;
  |     ^^^^^^^^^^^^^^^^^ cannot assign

Je ne comprends pas vraiment ce que cela signifie, car j'ai fait le HashMap mutable. Lorsque j'essaie de mettre à jour un élément dans un vector, j'obtiens le résultat attendu:

let mut my_vec = vec![1, 2, 3];

my_vec[0] += 10;
println! {"{:?}", my_vec};
// [11, 2, 3]

Qu'est-ce qui diffère de HashMap que j'obtiens l'erreur ci-dessus? Existe-t-il un moyen de mettre à jour une valeur?

42
Akavall

L'indexation immuable et l'indexation mutable sont fournies par deux traits différents: Index et IndexMut , respectivement.

Actuellement, HashMap n'implémente pas IndexMut, tandis que Vec le fait .

Le commit qui a supprimé l'implémentation de HashMap de IndexMut indique:

Cette validation supprime les implants IndexMut sur HashMap et BTreeMap, afin de pérenniser l'API contre l'inclusion éventuelle d'un trait IndexSet.

Je crois comprendre qu'un caractère hypothétique IndexSet vous permettrait d'attribuer de nouvelles valeurs à un HashMap, et pas seulement de lire ou de muter les entrées existantes:

let mut map = HashMap::new();
map["key"] = "value";

Pour l'instant, vous pouvez utiliser get_mut :

*my_map.get_mut("a").unwrap() += 10;

Ou l'API entry :

*my_map.entry("a").or_insert(42) += 10;
66
Shepmaster