Rust生命周期疑问:可变数据借用触发存活时间不足错误的原因
为何变量a的可变性会导致Rust代码编译结果差异?
错误代码(编译失败)
fn main() { let e = 100; let mut a = (1,); let mut b = (&e,); { let mut c = (&mut a, &mut b); let f = &mut c; f.1 .0 = &(f.0 .0); } println!("{:?}", b); }
编译错误信息
error[E0597]: `c` does not live long enough --> src/main.rs:7:17 | 6 | let mut c = (&mut a, &mut b); | ----- binding `c` declared here 7 | let f = &mut c; | ^^^^^^ borrowed value does not live long enough 8 | f.1 .0 = &f.0 .0; 9 | } | - `c` dropped here while still borrowed 10 | println!("{:?}", b); | - borrow later used here For more information about this error, try `rustc --explain E0597`.
可编译代码
fn main() { let e = 100; let a = (1,); let mut b = (&e,); { let mut c = (&a, &mut b); let f = &mut c; f.1 .0 = &(f.0 .0); } println!("{:?}", b); }
差异原因
核心在于Rust对可变引用、共享引用的生命周期约束,以及临时值的生命周期提升规则存在差异:
错误代码的问题:
a是可变变量,所以&mut a是可变引用,c的类型为(&mut (i32,), &mut (&i32,))。- 执行
f.1.0 = &(f.0.0)时,f.0.0是&mut (i32,),解引用后得到元组(1,),&(...)会创建一个临时元组并取其引用。 - 由于
f.0是可变引用,Rust会将这个临时元组的生命周期绑定到c(因为f是&mut c)。但c在代码块结束后就被销毁了,而b里的引用还指向这个已销毁的临时值,导致生命周期不匹配,触发编译错误。
可编译代码的逻辑:
a是不可变变量,&a是共享引用,c的类型为(&(i32,), &mut (&i32,))。- 执行
f.1.0 = &(f.0.0)时,f.0.0是&(i32,),解引用后得到元组(1,),创建的临时元组会被Rust生命周期提升——它的生命周期会被延长到和main函数中的a一致,足以覆盖b后续的打印操作,因此不会出现生命周期冲突。
内容的提问来源于stack exchange,提问作者artzok
相关产品推荐
相关产品推荐

