我正在创建一系列包含对较低级别结构的可变引用的数据结构.我一直很乐意和我一起工作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)
D与C生命周期相比,我完全不了解正在发生的事情:我不明白终身不匹配是什么.
原始代码中的函数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)