Here is what I am trying to do:
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} }
But this raises an error:
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>`
Rust 2018
error[E0594]: cannot assign to data in a `&` reference --> src/main.rs:8:5 | 8 | my_map["a"] += 10; | ^^^^^^^^^^^^^^^^^ cannot assign
I don't really understand what that means, since I made the HashMap
mutable. When I try to update an element in a vector
, I get the expected result:
let mut my_vec = vec![1, 2, 3]; my_vec[0] += 10; println! {"{:?}", my_vec}; // [11, 2, 3]
What is different about HashMap
that I am getting the above error? Is there a way to update a value?
Indexing immutably and indexing mutably are provided by two different traits: Index
and IndexMut
, respectively.
Currently, HashMap
does not implement IndexMut
, while Vec
does.
The commit that removed HashMap
's IndexMut
implementation states:
This commit removes the IndexMut impls on HashMap and BTreeMap, in order to future-proof the API against the eventual inclusion of an IndexSet trait.
It's my understanding that a hypothetical IndexSet
trait would allow you to assign brand-new values to a HashMap
, and not just read or mutate existing entries:
let mut map = HashMap::new(); map["key"] = "value";
For now, you can use get_mut
:
*my_map.get_mut("a").unwrap() += 10;
Or the entry
API:
*my_map.entry("a").or_insert(42) += 10;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With