Rust中如何满足编译器对owned trait对象要求的'static生命周期约束
根因
Rust 的 trait 对象有默认生命周期约束规则:如果没有显式为 dyn Trait 指定生命周期标记,编译器默认会要求该 trait 对象满足 'static 生命周期。
你定义的 Filtered<'mmap> 类型别名仅声明了 trait 本身的泛型生命周期参数,没有指定 trait 对象自身的生命周期约束,因此编译器默认要求你装箱的 Bar<'mmap> 实例满足 'static,和你实际绑定到内存映射的非静态 'mmap 生命周期冲突。
修复步骤
- 修改
Filtered类型别名,为 trait 对象显式添加生命周期约束,声明该 trait 对象的存活周期不超过'mmap:
// 修改前 // type Filtered<'mmap> = Box<dyn Filterable<'mmap>>; // 修改后 type Filtered<'mmap> = Box<dyn Filterable<'mmap> + 'mmap>;
- (可选优化)调整
Filterabletrait 的方法签名,避免不必要的生命周期绑定:
原方法签名中&'mmap self要求必须将实例借出整个'mmap生命周期,会限制后续实例的使用。由于Foo<'mmap>、Bar<'mmap>内部持有的body本身已经是&'mmap [u8]类型,和实例自身的借用周期无关,因此可以简化签名:
trait Filterable<'mmap> { // 修改前 // fn filtered(&'mmap self) -> Collection<'mmap>; // 修改后 fn filtered(&self) -> Collection<'mmap>; }
对应 impl 块中的方法签名同步修改即可。
修复后完整代码
use memmap::MmapOptions; // 0.7.0 use std::fs::File; type Filtered<'mmap> = Box<dyn Filterable<'mmap> + 'mmap>; type Collection<'mmap> = Vec<Filtered<'mmap>>; struct Foo<'mmap> { body: &'mmap [u8], } struct Bar<'mmap> { body: &'mmap [u8], } trait Filterable<'mmap> { fn filtered(&self) -> Collection<'mmap>; } impl<'mmap> Filterable<'mmap> for Foo<'mmap> { fn filtered(&self) -> Collection<'mmap> { vec![Box::new(Bar { body: self.body }) as Filtered<'mmap>] } } impl<'mmap> Filterable<'mmap> for Bar<'mmap> { fn filtered(&self) -> Collection<'mmap> { vec![] } } fn main() { let file = File::open("any_file_will_do").unwrap(); let mmap = unsafe { MmapOptions::new().map(&file).unwrap() }; let foo = Foo { body: &mmap }; let bars = foo.filtered(); }
内容的提问来源于stack exchange,提问作者ahenshaw
相关产品推荐
相关产品推荐

