我想移动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,而不是检查密钥。有什么好办法吗?
尚不清楚上下文/约束是什么,因此根据这些约束,有各种不同影响和复杂程度的可能性
- 如果您不关心保留第一个条目的空版本,您可以只使用
HashMap::remove
,因为它返回已删除键的值:https://play.rust-lang.org/?version=stable&mode=调试&edition=2018&gist=1734142acb598bad2f460fdff028b6e - 否则,可以使用类似
mem::swap
的东西将键1持有的向量替换为空向量,然后可以更新键2持有的向量:https://play.rust-lang.org/?version=stable&mode=调试&edition=2018&gist=e05941cb4d7df8982af7c9437a0446 - 由于
HashMap
没有拆分,最后的选择是使用可变迭代器,迭代器本质上是不重叠的,因此它们提供了对单个值的可变引用,这意味着它们可以让您同时获得对两个值的可变参考,尽管代码要复杂得多:https://play.rust-lang.org/?version=stable&mode=调试&edition=2018&要点=87d3c0a151882ce2f47dda59dc089d70
虽然第三个选项必须遍历整个哈希图(这比通过哈希直接找到正确的条目效率低(,但它可能的优点是:;失去";v1的分配,如果v1将来会再次填充,这是有用的:在第一个选项中,v1被完全删除,在第二个选项中v1变成容量为0的向量(除非你交换了一个具有预定义容量的向量,但这仍然是一个额外的分配(
您可以将Vec
放入RefCell
中,将借用检查移动到运行时:
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::append
将值从一个矢量移动到另一个矢量。