参考在嵌套结构中的活动时间不够长

Ben*_*ord 6 rust

我正在创建一系列包含对较低级别结构的可变引用的数据结构.我一直很乐意和我一起工作A,但是我试图添加一个新图层.,,,实际上是一个状态机的协议解码的状态,但是我在这里删除了这一切:BCDABCD

struct A {}

fn init_A() -> A {
    A {}
}

struct B<'l> {
    ed: &'l mut A,
}

fn init_B(mut e: &mut A) -> B {
    B { ed: e }
}

struct C<'l> {
    pd: &'l mut B<'l>,
}

fn init_C<'l>(mut p: &'l mut B<'l>) -> C<'l> {
    C { pd: p }
}

struct D<'lifetime> {
    sd: &'lifetime mut C<'lifetime>,
}

fn init_D<'l>(mut p: &'l mut C<'l>) -> D<'l> {
    D { sd: p }
}

fn main() {
    let mut a = init_A();
    let mut b = init_B(&mut a);
    let mut c = init_C(&mut b);

    // COMMENT OUT THE BELOW LINE FOR SUCCESSFUL COMPILE
    let mut d = init_D(&mut c);
}
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

error[E0597]: `c` does not live long enough
  --> src/main.rs:38:1
   |
37 |     let mut d = init_D(&mut c);
   |                             - borrow occurs here
38 | }
   | ^ `c` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created
Run Code Online (Sandbox Code Playgroud)

DC生命周期相比,我完全不了解正在发生的事情:我不明白终身不匹配是什么.

Sve*_*ach 2

原始代码中的函数init_*()始终返回一个类型,其生命周期参数等于您传入的引用的生命周期。由于您以这种方式构建引用链,因此所有生命周期最终都会相同,并且 , ,的a类型,最终将成为,,,。直到 为止都很好,因为生命周期可以是 的范围,它满足所有约束。bcdAB<'a>C<'a>D<'a>c'ab

然而,一旦添加d到混合中,就没有单一的生命周期'a可以使所有引用都有效。生命'a不再是范围b,因为c活得不够长。它也不能是 的范围c,因为这对于 来说太短了b,所以编译器会出错。

通过解耦生命周期,所有变量都可以拥有自己的生命周期,并且一切都按预期工作。由于问题仅从 开始D,因此此时引入额外的生命周期就足够了。

struct A;

fn init_a() -> A {
    A {}
}

struct B<'a> {
    ed: &'a mut A,
}

fn init_b(ed: &mut A) -> B {
    B { ed }
}

struct C<'b> {
    pd: &'b mut B<'b>,
}

fn init_c<'b>(pd: &'b mut B<'b>) -> C<'b> {
    C { pd }
}

struct D<'c, 'b: 'c> {
    sd: &'c mut C<'b>,
}

fn init_d<'c, 'b: 'c>(sd: &'c mut C<'b>) -> D<'c, 'b> {
    D { sd }
}

fn main() {
    let mut a = init_a();
    let mut b = init_b(&mut a);
    let mut c = init_c(&mut b);
    let d = init_d(&mut c);
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接