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?
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;