异步闭包在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);
起初,我对此感到困惑:sum
在for_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());
}
游乐场