使用“异步”谓词进行过滤时如何避免在生命周期内发生错误?
How to avoid incurring in lifetime errors while filter with an `async` predicate?
使用 async
谓词来过滤值列表会使 Rust 抱怨生命周期。即使集合是 await
ed,这意味着谓词不会超过过滤值,Rust 仍然持怀疑态度。
下方完整重现playground here。请注意,它过滤我们宁愿通过引用传递的非复制结构,而不是我们可以复制并忘记而不会产生开销的简单值。
use futures::stream::iter;
use futures::StreamExt;
#[derive(Debug)]
struct Foo {
bar: usize
}
impl Foo {
fn new(bar: usize) -> Self {
Self {
bar
}
}
}
#[tokio::main]
async fn main() {
let arr = vec![
Foo::new(0),
Foo::new(1),
Foo::new(2)
];
let filtered = iter(arr)
.filter(|f| async {compute_baz(f).await > 0})
.collect::<Vec<_>>()
.await;
// should print Foo{bar:1} and Foo{bar:2}
println!("{:?}", filtered)
}
async fn compute_baz(foo: &Foo) -> usize {
// ...do lengthy task...
foo.bar
}
更新
正如@Ceasar 在下面指出的那样,异步函数不是 运行 并行的,可以做到吗?
我正在尝试做类似的事情:
let filter_mask = join_all(items.map(predicate));
let filtered = items.filter(|i| filter_mask[i]).collect::<Vec<_>>();
没有杂乱。
一个简单的解决方法是避免关闭:
let mut filtered = vec![];
for f in arr.iter() {
if compute_baz(f).await > 0 {
filtered.push(f);
}
}
使用 async
谓词来过滤值列表会使 Rust 抱怨生命周期。即使集合是 await
ed,这意味着谓词不会超过过滤值,Rust 仍然持怀疑态度。
下方完整重现playground here。请注意,它过滤我们宁愿通过引用传递的非复制结构,而不是我们可以复制并忘记而不会产生开销的简单值。
use futures::stream::iter;
use futures::StreamExt;
#[derive(Debug)]
struct Foo {
bar: usize
}
impl Foo {
fn new(bar: usize) -> Self {
Self {
bar
}
}
}
#[tokio::main]
async fn main() {
let arr = vec![
Foo::new(0),
Foo::new(1),
Foo::new(2)
];
let filtered = iter(arr)
.filter(|f| async {compute_baz(f).await > 0})
.collect::<Vec<_>>()
.await;
// should print Foo{bar:1} and Foo{bar:2}
println!("{:?}", filtered)
}
async fn compute_baz(foo: &Foo) -> usize {
// ...do lengthy task...
foo.bar
}
更新
正如@Ceasar 在下面指出的那样,异步函数不是 运行 并行的,可以做到吗?
我正在尝试做类似的事情:
let filter_mask = join_all(items.map(predicate));
let filtered = items.filter(|i| filter_mask[i]).collect::<Vec<_>>();
没有杂乱。
一个简单的解决方法是避免关闭:
let mut filtered = vec![];
for f in arr.iter() {
if compute_baz(f).await > 0 {
filtered.push(f);
}
}