Rust交换可变引用时的生命周期报错问题咨询
为什么Rust中重新赋值函数内的可变引用会触发生命周期错误?
问题本质
函数参数mut foo: &mut Foo的生命周期'1是编译器推断的,它代表这个引用必须在整个函数调用期间保持有效——因为调用方的foo变量在函数返回后还要继续使用,所以原引用的生命周期会绑定到调用方变量的存活周期。
当你执行foo = &mut foo2时,变量foo的类型是&'1 mut Foo,这意味着任何赋值给它的引用都必须满足'1的生命周期要求。但foo2是函数内部的局部变量,它的生命周期只到函数结束(第13行}处就会被销毁),远短于'1,因此编译器会报错,禁止这种可能产生悬垂引用的操作。
你可能觉得“只是修改了函数内部的引用指向,不会影响调用方”,但Rust的生命周期检查是编译期的类型约束,不是运行时行为。变量foo的类型在编译时就被确定为带'1生命周期的可变引用,无论你后续是否把这个引用返回给调用方,赋值操作都必须符合类型的生命周期要求。
解决方法
如果只是想在函数内部临时使用另一个局部变量的引用,不要复用原参数的变量,而是新建一个局部引用变量:
struct Foo { x: u32, y: u32 } fn do_something(mut foo: &mut Foo) { foo.x = 4; foo.y = 5; println!("foo.x = {}\nfoo.y = {}", foo.x, foo.y); let mut foo2 = Foo{x: 10, y: 20}; // 新建局部引用,生命周期仅覆盖当前使用范围 let foo_ref = &mut foo2; println!("foo_ref.x = {}\nfoo_ref.y = {}", foo_ref.x, foo_ref.y); } fn main() { let mut foo = Foo{x: 1, y: 2}; do_something(&mut foo); println!("foo.x = {}\nfoo.y = {}", foo.x, foo.y); }
这里foo_ref的生命周期是局部的,只需要覆盖到println调用即可,不需要满足原参数的'1生命周期,因此编译器会通过检查。
补充说明
如果一定要复用foo变量,理论上需要调整函数的生命周期参数,让编译器知道foo的生命周期可以被缩短,但这在你的场景下完全没必要——因为你根本不需要把指向foo2的引用带出函数,新建局部变量是更清晰、更符合Rust设计意图的做法。
内容的提问来源于stack exchange,提问作者tweekz
相关产品推荐
相关产品推荐

