关于Rust生命周期的疑问:两段相似代码为何一错一正?
Rust生命周期困惑:Box与引用的行为差异
原本以为自己已清晰理解Rust生命周期,却发现知识盲区——以下第一段用Box包裹trait对象的代码会触发E0597错误,但将Box替换为引用后的第二段代码却能正常运行,想知道原因:
第一段报错代码
struct Token<'a> { slice: &'a str, } struct WrappedToken<'a>(&'a Token<'a>); trait ToWrappedToken<'a> { fn to(&'a self) -> WrappedToken<'a>; } impl<'a> ToWrappedToken<'a> for Token<'a> { fn to(&'a self) -> WrappedToken<'a> { WrappedToken(self) } } fn to_wrap<'a>(token: Token<'a>) -> Box<dyn ToWrappedToken<'a> + 'a> { Box::new(token) } fn main() { let token = Token { slice: "It's working well.", }; let r = to_wrap(token); r.to(); }
错误信息
error[E0597]: `*r` does not live long enough --> src/main.rs:26:5 | 25 | let r = to_wrap(token); | - binding `r` declared here 26 | r.to(); | ^ borrowed value does not live long enough 27 | } | - | | | `*r` dropped here while still borrowed | borrow might be used here, when `r` is dropped and runs the destructor for type `Box<dyn ToWrappedToken<'_>>` For more information about this error, try `rustc --explain E0597`.
第二段正常代码
struct Token<'a> { slice: &'a str, } struct WrappedToken<'a>(&'a Token<'a>); trait ToWrappedToken<'a> { fn to(&'a self) -> WrappedToken<'a>; } impl<'a> ToWrappedToken<'a> for Token<'a> { fn to(&'a self) -> WrappedToken<'a> { WrappedToken(self) } } fn to_wrap<'a>(token: &'a Token<'a>) -> &'a dyn ToWrappedToken<'a> { token } fn main() { let token = Token { slice: "It's working well.", }; let r = to_wrap(&token); r.to(); }
核心原因分析
两段代码的差异本质是被包裹对象的生命周期与trait方法要求的引用生命周期是否匹配,以及Rust对trait对象析构的安全检查:
Box版本报错的关键原因:
to_wrap将Token移动到Box中,此时Box内Token的生命周期是变量r的生命周期(从创建到main函数结束)。ToWrappedToken<'a>trait的to方法要求接收&'a self——这里的'a是Token结构体的生命周期参数(对应slice的'static生命周期)。- 调用
r.to()时,Box自动解引用为&*r,但*r的生命周期短于'a,无法满足&'a self的要求。 - 更重要的是,Rust无法确定
trait对象的析构函数是否会保留to方法返回的WrappedToken中的引用。当r被销毁时,*r`会先被释放,若析构函数尝试访问已销毁的对象,就会产生悬垂引用,因此编译器直接报错阻止这种风险。
引用版本正常的逻辑:
to_wrap返回的&'a dyn ToWrappedToken<'a>直接指向原Token实例,其生命周期'a与Token的生命周期参数完全一致。- 调用
r.to()时,&'a self就是对原Token的引用,生命周期完全匹配,编译器可以确认Token的生命周期足够长,不会在引用使用期间被销毁,因此通过安全检查。
内容的提问来源于stack exchange,提问作者Irfan Hossain Bhuiyan Student
相关产品推荐
相关产品推荐

