异步移动闭包与折叠



异步闭包在Rust中仍然不稳定,正如在相关问题|_| async move {}async move |_| {}之间的区别中所指出的,我并不真正理解这个问题的答案。

据我所知,以下是而不是异步闭包:

let mut sum: i32 = 0;
stream::iter(1..25)
.map(compute)
.buffered(12)
.for_each(|result| async move { sum+=result; })
.await;
println!("->{}", sum);

起初,我对此感到困惑:sumfor_each中使用,但它不会被移动,否则println!会产生编译器错误。然而,编译器给出了一个警告,即";分配给CCD_ 6的值从不被读取";。但事实上,sum是复制的。

以下是完整的示例代码

use futures::{stream, StreamExt};
use rand::{thread_rng, Rng};
use std::time::Duration;
async fn compute(i: i32) -> i32 {
let mut rng = thread_rng();
let sleep_ms: u64 = rng.gen_range(0..1000);
tokio::time::sleep(Duration::from_millis(sleep_ms)).await;
println!("#{} done", i);
i * i
}
async fn sum_with_fold() {
let sum = stream::iter(1..25)
.map(compute)
.buffered(12)
.fold(0, |sum,x| async move {sum+x} )
.await;
println!("->{}", sum);
}
async fn sum_with_closure() {
let mut sum: i32 = 0;
stream::iter(1..25)
.map(compute)
.buffered(12)
.for_each(|result| async move { sum+=result; })
.await;
println!("->{}", sum);
}
#[tokio::main]
async fn main() {
sum_with_fold().await;
sum_with_closure().await;
}
// Cargo.toml:
// [dependencies]
// futures = "0.3"
// rand = "0.8"
// tokio = { version = "1", features = ["full"] }

折叠工作正常,而sum_with_closure在复制的sum上工作,并且无法检索此sum

我做对了吗?能修好吗?也就是说,有没有一种方法可以用这样的盖子来折叠?或者我确实遇到了不稳定的异步闭包特性?

这可以用for_each完成,但当前的Rust无法在编译时检查寿命是否正确,因此您需要使用RefCell来启用运行时检查(性能成本很低(:

async fn sum_with_closure() {
use std::cell::RefCell;
let sum = RefCell::new (0);
let sumref = ∑
stream::iter(1..25)
.map(compute)
.buffered(12)
.for_each(|result| async move { *sumref.borrow_mut() +=result; })
.await;
println!("->{}", sum.into_inner());
}

游乐场

最新更新