我在 Rust 中遇到的一个常见模式是这样的:
struct Foo { /*...*/ }
struct FooProcessor {
foos: Vec<&'??? mut Foo>, // this lifetime is the issue, see explanation below
// other data structures needed for processing Foos ....
}
impl FooProcessor {
pub fn process(&mut self, input: &mut [Foo]) {
// some example operation that requires random access to a subset
self.foos.extend(input.iter().filter(|f| f.some_property()));
self.foos.sort();
// work some more on the Foos...
// remove all references to the processed Foos
self.foos.clear();
}
}
问题在于
FooProcessor::foos
的生命周期,正如上面的问号所强调的那样。所有对 Foo
的引用都会在 process()
结束时被清除,但借用检查器当然不知道这一点。
FooProcessor
通常是一个大的、寿命长的对象,我不想每次调用Vec<&Foo>
时都重新分配process()
(甚至不使用一些SmallVec
东西)。
有没有一种好方法可以解决这个问题,并且每次我有这种模式时不需要使用不安全代码(生命周期变换/指针)? (如果解决方案涉及使用某个板条箱,那么该板条箱内部使用不安全当然没问题)。
您可以在传递给
FooProcessor
的 &mut [Foo]
的生命周期内使 process()
变得通用:
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct Foo {}
struct FooProcessor<'a> {
foos: Vec<&'a mut Foo>,
}
impl<'a> FooProcessor<'a> {
pub fn process(&mut self, input: &'a mut [Foo]) {
self.foos
.extend(input.iter_mut().filter(|f| f.some_property()));
self.foos.sort();
// ...
self.foos.clear();
}
}