'How to modify an entry in a HashMap after more than one entry has been added to the HashMap in Rust
The following code works ...
let mut hash_map: HashMap<String, String> = HashMap::new();
let n1 = "n1".to_string();
let no1 = hash_map.entry(n1.clone()).or_insert(n1.clone());
no1.clear();
But at the moment I add a second entry to the HashMap it does not compile any more. So what do I have to change so that I can add more than one element to a HashMap and still be able to modify elements of the HashMap afterwards?
let mut hash_map: HashMap<String, String> = HashMap::new();
let n1 = "n1".to_string();
let n2 = "n2".to_string();
let no1 = hash_map.entry(n1.clone()).or_insert(n1.clone());
let no2 = hash_map.entry(n2.clone()).or_insert(n2.clone());
no1.clear();
The code above results in the following compile error:
error[E0499]: cannot borrow `hash_map` as mutable more than once at a time
--> src/main.rs:127:15
|
126 | let no1 = hash_map.entry(n1.clone()).or_insert(n1.clone());
| -------------------------- first mutable borrow occurs here
127 | let no2 = hash_map.entry(n2.clone()).or_insert(n2.clone());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
128 |
129 | no1.clear();
| ----------- first borrow later used here
Solution 1:[1]
no1 holds a mutable borrow on the map over the line you try to insert the second element. If you want exactly this order of operations then you can't retain the reference in no1. You'll have to re-fetch the reference by key:
let mut hash_map: HashMap<String, String> = HashMap::new();
let n1 = "n1".to_string();
let n2 = "n2".to_string();
hash_map.entry(n1.clone()).or_insert(n1.clone());
hash_map.entry(n2.clone()).or_insert(n2.clone());
hash_map.get_mut(&n1).expect("n1 present").clear();
Holding a reference to an element of a collection has nearly the same effect on the borrow checker as holding a reference to the entire collection.
- If you hold a mutable reference to an element in the collection, you can't do anything with the collection until you drop the reference.
- If you hold an immutable reference to an element in the collection, you can get immutable references to other elements in the collection, but you can't modify other elements (without interior mutability), nor the collection itself.
There is a reason for this. What happens if inserting n2 causes the map to need to grow? This would invalidate the reference in no1 as the values are moved to new locations. Rust is doing its job and protecting you from doing something that isn't memory-safe.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
