我正在尝试找到在结构中包含Vec<RwLockReadGuard<..>>
的方法。该Vec
仅在对结构具有独占访问权的函数持续时间内为非空,将其用作可重用Vec以避免每次调用该函数时进行分配。显示错误的最小可复制示例在问题的底部。
动机:我有一个由RwLock
保护的数据向量的向量,内部Vec
代表被异步修改的数据流。有时,我调用Process::process
压缩这些流并使用process_ts
函数处理压缩的“ 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>>>,
|
为什么需要使用期限以及由此产生的错误对我来说是显而易见的。但是我想知道是否有一些解决方法,也许是一个将不安全的API提供给不安全的实现的包装箱,这将使我能够做我需要的事情。我想象它只允许从封闭内部访问可重复使用的Vec,以确保在删除封闭之类的东西时清除Vec,我不确定。
我正在尝试找到在结构中包含Vec
Vec
。使用它来存储RwLockReadGuard<'a, Vec<T>>
类型的元素一段生命周期'a
,然后清除向量并将其放置为RwLockReadGuard<'b, Vec<T>>
类型的元素,其中生命周期'b
是与'a
不同的生命周期(实际上没有与之重叠),等等。这是行不通的,因为RwLockReadGuard<'a, Vec<T>>
与RwLockReadGuard<'b, Vec<T>>
的类型不同,并且我们无法更改Vec
所保存的元素的类型。但是也许真正的目标不是用相同的Vec
来保存这些不同类型的元素(这不可能),而是避免需要重新分配每个新的Vec
。我们可能会问,是否可以从旧的Vec
回收已分配的内存,从而跳过不必分配下一个Vec
的情况?好吧,用一些非常丑陋,不安全的代码,可能有可能只分配一个Vec<u8>
,然后在每次调用process
时都要进行一些指针争夺,以将其就地转换为所需类型的Vec
(大小为零但容量不为零);这可能很难正确完成,并且需要根据Vec
中std
实现的内部细节而定。