-1

我想将 HashMap<u64, Vec> key=1 的元素移动到 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());
    }
}

得到错误:

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 检查借用整个 HashMap,而不是检查密钥。有什么好办法吗?

4

2 回答 2

4

目前尚不清楚上下文/约束是什么,因此取决于这些,存在不同影响和复杂程度的各种可能性

虽然第三个选项必须遍历整个 hashmap(这比通过散列直接找到正确的条目效率低),但它可能具有不会“丢失”v1 的分配的优势,这在将来再次填充 v1 时很有用:在第一个选项中 v1 被完全删除,在第二个选项中 v1 成为容量为 0 的向量(除非您交换具有预定义容量的向量,但这仍然是一个额外的分配)

于 2020-11-19T09:09:47.037 回答
1

您可以将借用检查移动到运行时VecRefCell

use std::cell::RefCell;
use std::collections::HashMap;

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

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

    // move the elements of key=1 to key=2
    vec2.append(&mut vec1);
}

提示:使用Vec::appendwhich 将值从一个向量移动到另一个向量。

于 2020-11-19T09:26:51.713 回答