如何在比赛中结束借用或者如果让表达?

时间:2015-11-03 09:49:15

标签: rust

我使用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的值,但这并不会结束借用。通常我会使用{}块来限制借用,但在matchif let中似乎无法做到这一点。

结束借款的惯用方法是什么,以便我可以获得新的可变借款?

2 个答案:

答案 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);
}

鉴于您未提供Nodeself.pages的定义,很难使上述代码完全正确,但它应该大致正确。当然,仅当leaf_pageleaf_node不包含对self.pagesself的引用时,它才有效,否则您将无法访问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));
};