从HashMap或Vec返回引用会导致借用超出其范围?

从HashMap或Vec返回引用会导致借用超出其范围?

我遇到了一个持续的编译错误,Rust抱怨我在尝试不断地借款时有一个不可变的借入,但是不变的借入来自另一个范围,而且我不会从它带来任何东西。

我有一些代码来检查映射中的值,如果它是存在的,就返回它,否则它需要以各种方式修改映射。问题是,我似乎找不到一种方法让RUST让我做这两种操作,即使这两个操作是完全分开的。

下面是一些与我的代码结构相同的荒谬代码,并展示了问题所在:

use std::collections::BTreeMap;fn do_stuff(map: &mut BTreeMap<i32, i32>, key: i32) -> Option<&i32> {
    // extra scope in vain attempt to contain the borrow
    {
        // borrow immutably
        if let Some(key) = map.get(&key) {
            return Some(key);
        }
    }

    // now I'm DONE with the immutable borrow, but rustc still thinks it's borrowed

    map.insert(0, 0); // borrow mutably, which errors
    None}

此错误包括:

error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
  --> src/lib.rs:14:5
   |
3  | fn do_stuff(map: &mut BTreeMap<i32, i32>, key: i32) -> Option<&i32> {
   |                  - let's call the lifetime of this reference `'1`
...
7  |         if let Some(key) = map.get(&key) {
   |                            --- immutable borrow occurs here
8  |             return Some(key);
   |                    --------- returning this value requires that `*map` is borrowed for `'1`
...
14 |     map.insert(0, 0); // borrow mutably, which errors
   |     ^^^^^^^^^^^^^^^^ mutable borrow occurs here

这对我来说毫无意义。不可变的借入怎么会比那个范围更长?!其中一个分支match通过return而另一个则什么也不做就离开了范围。

我以前见过这种情况,我在其他变量中错误地将借款从范围外走私出去,但这里不是这样的!

是的,借用是通过return语句,但这是荒谬的,阻止借入更低的功能-程序不可能返回并继续前进!如果我在那里返回其他东西,错误就会消失,所以我认为这就是借阅检查程序被挂起来的原因。我觉得这就像个虫子。

不幸的是,我一直无法找到任何方法来重写它而不会碰到同样的错误,所以如果是这样的话,这是一个特别令人讨厌的错误。


森栏
浏览 400回答 2
2回答

守着一只汪

不幸的是,.entry()不适合此函数所需的操作。我意识到了非词汇范围的问题,通常我可以解决这个问题,但在这种情况下,我还没能想出一些不做重复工作的东西,不管解决办法有多么丑陋…。另外,通常添加一个作用域可以解决这个问题,但在这里它并不有效;即使将一个借入到另一个函数也没有帮助。
打开App,查看更多内容
随时随地看视频慕课网APP