Rust中trait对象引用后的+'a生命周期标注有什么作用?
问题本质:trait对象的隐含生命周期约束
Rust 中所有 dyn Trait 形式的 trait 对象都自带一个生命周期约束,它的作用是限定所有实现了该 trait 的具体类型,其内部包含的所有引用的存活时长,都不能短于这个生命周期,避免 trait 对象持有悬垂引用。
为什么省略 + 'a 也能正常运行
你观察到的两种写法等价,是因为 Rust 有生命周期自动省略规则:当 trait 对象出现在引用的后面时(即 &'a (dyn FooTrait) 这种形式),编译器会自动把 trait 对象的生命周期补全为引用的生命周期,也就是你写 &'a (dyn FooTrait) 编译器会默认当成 &'a (dyn FooTrait + 'a) 处理,所以两种写法在这个场景下没有区别,自然不会报错。
什么时候必须手动标注 + 'a
只有当 trait 对象没有被引用直接包裹的时候,你才需要手动标注它的生命周期,最常见的场景是 trait 对象被放在智能指针里:
- 如果你写
Box<dyn FooTrait>,编译器默认会给 trait 对象绑定'static生命周期,只能放入内部没有非'static引用的类型 - 如果你要支持内部带短生命周期引用的实现类,就必须手动写
Box<dyn FooTrait + 'a>,明确标注 trait 对象的生命周期和'a绑定
举个实际的例子,假设我们有一个内部带引用的类型实现了 FooTrait:
struct Baz<'b> { name: &'b str, } impl<'b> FooTrait for Baz<'b> { fn print(self) { println!("It's a Baz named {}", self.name); } }
这时候 dyn FooTrait + 'a 的约束就会要求 Baz 内部的 'b 生命周期必须长等于 'a,保证 Baz 里的 name 引用在 Bar 的整个存活周期内都是有效的,不会出现悬垂引用。
内容的提问来源于stack exchange,提问作者Rahn
相关产品推荐
相关产品推荐

