可变借款似乎比其范围更长

Mic*_*den 7 rust

试图编译这个程序我被困在借阅检查器上:

use std::collections::BTreeMap;

type Object<'a> = BTreeMap<&'a str, i32>;

struct Root<'a>(Object<'a>);

struct Sub<'a>(&'a mut Object<'a>, &'a str);

impl<'a> Root<'a> {
    fn borrow_mut(&'a mut self, data: &'a str) -> Sub<'a> {
        Sub(&mut self.0, data)
    }

    fn borrow(&self) {
        println!("{:?}", self.0);
    }
}

fn main() {
    let mut me = Root(Object::new());
    {
        me.borrow_mut("data!");
    }
    me.borrow();
}
Run Code Online (Sandbox Code Playgroud)

(游乐场)

我明白了:

error[E0502]: cannot borrow `me` as immutable because it is also borrowed as mutable
  --> src/main.rs:24:5
   |
22 |         me.borrow_mut("data!");
   |         -- mutable borrow occurs here
23 |     }
24 |     me.borrow();
   |     ^^ immutable borrow occurs here
25 | }
   | - mutable borrow ends here
Run Code Online (Sandbox Code Playgroud)

看起来可变借款应该在此之前结束,me.borrow()但借款检查员坚持认为它在结束时main结束.

要快速解释我想要实现的目标:

  1. 创建父结构来保存数据
  2. 创建子类别的数据并将其存储在父级中
  3. 使用此构建器样式模式来生成MongoDB查询

Mat*_* M. 8

你正在与一生的问题发生冲突.

您的计划中有多个不同的生命周期:

  • type Object<'a> = BTreeMap<&'a str, i32>; =>这是一个
  • &'a mut Object<'a> =>这里最多有两个
  • struct Sub<'a>(&'a mut Object<'a>, &'a str); =>这里有三个

显然,没有理由提到Object<'a>具有与&str内部相同的寿命BTreeMap.但是,你告诉编译器你希望两个生命周期都一样!

当你写:

struct Sub<'a>(&'a mut Object<'a>, &'a str);
Run Code Online (Sandbox Code Playgroud)

你告诉编译器:

  • &str内心的生命BTreeMap
  • 引用的生命周期 Object<'_>
  • &str陪伴的生命Object<'_>

都是一样的.

你过度约束了这些要求; 因此,没有解决方案可以满足他们.

增加一个自由度就足够了!我们只是将引用Object<'_>的生命周期与&str浮动周期的生命周期不同:

struct Sub<'a, 'b: 'a>(&'a mut Object<'b>, &'b str);

impl<'b> Root<'b> {
    fn borrow_mut<'a>(&'a mut self, data: &'b str) -> Sub<'a, 'b> {
        Sub(&mut self.0, data)
    }

    fn borrow(&self) {
        println!("{:?}", self.0);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意微妙'b: 'a:

  • Object<'b> 包含对其生命周期为的内容的引用 'b
  • Object<'b>(表示'a)的引用的生命周期必须比'b(或者你有一些死的引用?)

因此,我们说'b会超越'a使用'b: 'a.

就是这样.简单地放宽要求允许编译器允许您的代码进行编译.


请注意,一般情况下,如果你发现自己写的东西就像&'a &'a str你做错了.如果你仔细想想,你会发现,为了创造的东西的引用,首先必须.因此,对象的引用必然比对象本身具有更短的生命周期(如此轻微).