我使用HashMap
来存储枚举。我想从HashMap
获取一个值,如果该值是特定的枚举变体,我想在HashMap
中插入一个修改后的值副本。
我想出的代码如下:
if let Node::LeafNode(mut leaf_node) = *(self.pages.get(&page).unwrap()) {
let mut leaf_node = leaf_node.clone();
// ...
self.pages.insert(leaf_page,Node::LeafNode(leaf_node));
}
这不会编译,因为借用self.pages
会持续到if let
- 块结束,self.pages.insert
是可变借用。
我试图用值的副本来隐藏HashMap
的值,但这并不会结束借用。通常我会使用{}
块来限制借用,但在match
或if let
中似乎无法做到这一点。
结束借款的惯用方法是什么,以便我可以获得新的可变借款?
答案 0 :(得分:4)
目前无法做到这一点。你想要的是non-lexical borrows,它还没有在Rust中实现。同时,您应该使用Entry
API来处理地图 - 在大多数情况下,它应该足够了。在这种特殊情况下,我不确定条目是否适用,但您总是可以执行类似
let mut result = None;
if let Some(&Node::LeafNode(ref leaf_node)) = self.pages.get(&page) {
let mut leaf_node = leaf_node.clone();
// ...
result = Some((leaf_page, leaf_node));
}
if let Some((leaf_page, leaf_node)) = result {
self.pages.insert(leaf_page, leaf_node);
}
鉴于您未提供Node
和self.pages
的定义,很难使上述代码完全正确,但它应该大致正确。当然,仅当leaf_page
和leaf_node
不包含对self.pages
或self
的引用时,它才有效,否则您将无法访问self.pages
。
答案 1 :(得分:0)
以下是使用match
的Vladimir解决方案:
let mut result = match self.pages.get(&page) {
Some(&Node::LeafNode(ref leaf_node)) => Some(leaf_node.clone()),
_ => None,
};
if let Some(leaf_node) = result {
// ...
self.pages.insert(page_number, Node::LeafNode(leaf_node));
};