Search code examples
rusthashmapborrow

Rust check borrow with the whole HashMap, not check the key, is there any good way?


I want move the elements of HashMap<u64, Vec> key=1 to key=2

use std::collections::HashMap;

fn main() {
    let mut arr: HashMap<u64, Vec<u64>> = HashMap::new();
    arr.insert(1, vec![10, 11, 12]); // in fact, elments more than 1,000,000, so can't use clone()
    arr.insert(2, vec![20, 21, 22]);

    // in fact, following operator is in recusive closure, I simplify the expression:
    let mut vec1 = arr.get_mut(&1).unwrap();
    let mut vec2 = arr.get_mut(&2).unwrap();

    // move the elements of key=1 to key=2
    for v in vec1 {
        vec2.push(vec1.pop().unwrap());
    }
}

got error:

error[E0499]: cannot borrow `arr` as mutable more than once at a time
  --> src/main.rs:10:20
   |
9  |     let mut vec1 = arr.get_mut(&1).unwrap();
   |                    --- first mutable borrow occurs here
10 |     let mut vec2 = arr.get_mut(&2).unwrap();
   |                    ^^^ second mutable borrow occurs here
11 |     for v in vec1 {
   |              ---- first borrow later used here

Rust check borrow with the whole HashMap, not check the key. Is there any good way ?


Solution

  • It's not clear what the context / constraints are, so depending on those there are various possibilities of different impact and levels of complexity

    While the third option has to traverse the entire hashmap (which is less efficient than directly finding the correct entries by hashing), it has the possible advantage of not "losing" v1's allocation which is useful if v1 will be filled again in the future: in the first option v1 is completely dropped, and in the second option v1 becomes a vector of capacity 0 (unless you swap in a vector with a predefined capacity, but that's still an extra allocation)