结构体中的Rust生命周期问题:为何可变借用冲突仍存在?
问题原理
问题出在cast方法的生命周期标注上:
- 结构体
Test<'s>的生命周期's对应它持有的&'s mut i32的有效时长。 - 你给
cast方法的self参数标注了&'s mut self,这相当于强制要求对self的可变借用生命周期和结构体本身的's生命周期完全一致。 - 当调用
a.cast()时,Rust会认为你把a做了一个从创建到销毁全程的可变借用——哪怕你把调用放在大括号里,这个借用的生命周期也不会被大括号限制,因为它被绑定到了's。后续调用a.mutate()时,这个长生命周期的借用还没结束,自然触发可变借用冲突。
解决方案
修改cast方法的生命周期标注,不要将self的借用绑定到结构体的's生命周期,让编译器自动推导一个临时的、更短的借用周期即可:
struct Test<'s>(&'s mut i32); impl<'n, 's: 'n> Test<'s> { fn new(i: &'s mut i32) -> Self { Self(i) } // 去掉self参数上的's标注,让推导自动处理 fn cast(&mut self) -> Test<'n> { Test(self.0) } fn mutate(&mut self) { self.0.add_assign(10); println!("Mutate: {}", self.0); } } fn test() { let mut i = 5; let mut a = Test::new(&mut i); { a.cast().mutate(); // 这里的借用生命周期被限制在大括号内 } a.mutate(); // 此时之前的借用已结束,可正常调用 } fn main() { test(); }
运行这段代码会输出:
Mutate: 15 Mutate: 25
内容的提问来源于stack exchange,提问作者Danila
相关产品推荐
相关产品推荐

