【发布时间】:2020-06-11 18:05:09
【问题描述】:
我的算法使用Vec<RwLockReadGuard<..>> 来处理数据。该算法被重复调用,我不想每次调用它时都分配Vec,如果我可以在处理结束时只使用clear(),我会很高兴,并在下一次重用它将其存储在与数据处理相关的同一结构中。但是,RwLockReadGuard 的生命周期比持有结构的可能生命周期短。由于我只在数据处理函数内部使用Vec,而在它外部它总是空的,我还能以某种方式将它存储在结构中吗?是否有一个板条箱或成语可以帮助我解决这个问题?
显示问题的最小可重现示例位于问题的底部。
如果我每次都分配Vec,这就是它的样子:
#[derive(Clone)]
pub struct T;
pub fn process_ts(ts: &[T]) {
unimplemented!();
}
struct Process {
locked_ts: Vec<RwLock<Vec<T>>>,
}
impl Process {
pub fn process(&self) {
let mut ts: Vec<T> = Vec::with_capacity(self.locked_ts.len());
let guards: Vec<RwLockReadGuard<Vec<T>>> = self
.locked_ts
.iter()
.map(|locked_t| locked_t.read().unwrap())
.collect();
let n = guards.iter().map(|guard| guard.len()).min().unwrap();
for i in 0..n {
ts.clear();
for t in &guards {
ts.push(t[i].clone());
process_ts(&ts);
}
}
}
}
我不喜欢这个解决方案的是,每次调用Process::process 时,都会分配ts: Vec<T> 和guards: Vec<RwLockReadGuard<Vec<T>>>。我可以摆脱ts:
struct ProcessReuseTs {
locked_ts: Vec<RwLock<Vec<T>>>,
reusable_ts: Vec<T>,
}
impl ProcessReuseTs {
pub fn process(&mut self) {
let guards: Vec<RwLockReadGuard<Vec<T>>> = self
.locked_ts
.iter()
.map(|locked_t| locked_t.read().unwrap())
.collect();
let n = guards.iter().map(|guard| guard.len()).min().unwrap();
for i in 0..n {
self.reusable_ts.clear();
for t in &guards {
self.reusable_ts.push(t[i].clone());
process_ts(&self.reusable_ts);
}
}
}
}
但是如何提取guards?
use std::sync::{RwLock, RwLockReadGuard};
#[derive(Clone)]
pub struct T;
pub fn process_ts(ts: &[T]) {
unimplemented!();
}
struct ProcessReuseBoth {
locked_ts: Vec<RwLock<Vec<T>>>,
reusable_ts: Vec<T>,
reusable_guards: Vec<RwLockReadGuard<Vec<T>>>,
}
impl ProcessReuseBoth {
pub fn process(&mut self) {
self.reusable_guards.clear();
self.reusable_guards.extend(
self.locked_ts
.iter()
.map(|locked_t| locked_t.read().unwrap()),
);
let n = self
.reusable_guards
.iter()
.map(|guard| guard.len())
.min()
.unwrap();
for i in 0..n {
self.reusable_ts.clear();
for t in &self.reusable_guards {
self.reusable_ts.push(t[i].clone());
process_ts(&self.reusable_ts);
}
}
self.reusable_guards.clear();
}
}
pub fn main() {
unimplemented!()
}
不能用
编译error[E0106]: missing lifetime specifier
--> src/main.rs:13:26
|
13 | reusable_guards: Vec<RwLockReadGuard<Vec<T>>>,
|
【问题讨论】:
-
请edit您的问题并粘贴您收到的确切和全部错误 - 这将帮助我们了解问题所在,以便我们提供最佳帮助。有时试图解释错误消息很棘手,实际上错误消息的不同部分很重要。请使用直接运行编译器的消息,而不是 IDE 生成的消息,它可能会尝试为您解释错误。
-
很难回答您的问题,因为它不包含minimal reproducible example。我们无法分辨代码中存在哪些 crate(及其版本)、类型、特征、字段等。如果您尝试在Rust Playground 上重现您的错误,如果可能的话,这将使我们更容易为您提供帮助,否则在一个全新的 Cargo 项目中,然后在edit 您的问题中包含附加信息。您可以使用Rust-specific MRE tips 来减少您在此处发布的原始代码。谢谢!
-
看来Why can't I store a value and a reference to that value in the same struct? 的答案可能会回答您的问题。如果没有,请edit您的问题来解释差异。否则,我们可以将此问题标记为已回答。
-
我添加了最小可重现示例和确切错误。您建议的答案非常广泛,涵盖了很多主题,我看不出它如何解决我的问题(也许可以,但我看不出如何应用它)。我想说不同之处在于,在我的情况下,引用的 Vec 在 fn 之外始终为空,并且具有对结构的独占(&mut)访问。它基本上仅用作 fn 内部临时使用的预分配区域。难道没有一些巧妙的方法可以利用这个属性吗?