为什么这个可变借用超出了它的范围?

rme*_*dor 11 rust borrow-checker

在我期望可变借用结束之后,我遇到了关于同时使用可变和不可变借用的令人困惑的错误。我对类似问题(1 , 2 , 3 , 4 , 5)进行了大量研究,这让我相信我的问题与词法生命周期有关(尽管打开 NLL 功能并每晚编译并没有) t 改变结果),我只是不知道是什么;我的情况似乎不适合其他问题的任何场景。

pub enum Chain<'a> {
    Root {
        value: String,
    },
    Child {
        parent: &'a mut Chain<'a>,
    },
}

impl Chain<'_> {
    pub fn get(&self) -> &String {
        match self {
            Chain::Root { ref value } => value,
            Chain::Child { ref parent } => parent.get(),
        }
    }

    pub fn get_mut(&mut self) -> &mut String {
        match self {
            Chain::Root { ref mut value } => value,
            Chain::Child { ref mut parent } => parent.get_mut(),
        }
    }
}

#[test]
fn test() {
    let mut root = Chain::Root { value: "foo".to_string() };

    {
        let mut child = Chain::Child { parent: &mut root };

        *child.get_mut() = "bar".to_string();
    } // I expect child's borrow to go out of scope here

    assert_eq!("bar".to_string(), *root.get());
}
Run Code Online (Sandbox Code Playgroud)

操场

错误是:

error[E0502]: cannot borrow `root` as immutable because it is also borrowed as mutable
  --> example.rs:36:36
   |
31 |         let mut child = Chain::Child { parent: &mut root };
   |                                                --------- mutable borrow occurs here
...
36 |     assert_eq!("bar".to_string(), *root.get());
   |                                    ^^^^
   |                                    |
   |                                    immutable borrow occurs here
   |                                    mutable borrow later used here
Run Code Online (Sandbox Code Playgroud)

我理解为什么在那里发生不可变借用,但我不明白在那里如何使用可变借用。如何在同一个地方使用两者?我希望有人可以解释正在发生的事情以及我如何避免它。

kmd*_*eko 8

总之,&'a mut Chain<'a>是极其有限和普遍的。

对于不可变引用&T<'a>,允许编译器'a在必要时缩短生命周期以匹配其他生命周期或作为 NLL 的一部分(情况并非总是如此,这取决于是什么T)。但是,它不能为可变引用这样做&mut T<'a>,否则您可以为其分配一个生命周期较短的值。

因此,当编译器尝试协调引用和参数链接时的生命周期时,引用&'a mut T<'a>的生命周期在概念上会扩展以匹配参数的生命周期。这实质上意味着您创建了一个永远不会被释放的可变借用。

基本上,只有当嵌套值在其生命周期内是协变的,才能创建基于引用的层次结构。其中不包括:

  • 可变引用
  • 特征对象
  • 具有内部可变性的结构

请参阅这些变化在操场上看到如何预期这些不太正常工作。

也可以看看:


归档时间:

查看次数:

476 次

最近记录:

4 年,1 月 前