异步移动闭包与折叠

Async move closure vs. fold

提问人:mcmayer 提问时间:10/28/2022 更新时间:10/28/2022 访问量:270

问:

异步闭包在 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_eachprintln!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_closuresumsum

我做对了吗,可以修复吗?也就是说,有没有办法用这样的闭合来折叠?还是我确实遇到了不稳定的异步闭包功能?

异步 Rust 闭包

评论


答:

1赞 Jmb 10/28/2022 #1

这可以通过 来完成,但当前的 Rust 无法在编译时检查生存期是否正确,因此您需要使用 a 来启用运行时检查(性能成本很小):for_eachRefCell

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());
}

操场

评论

0赞 Chayim Friedman 10/28/2022
StreamExt::for_each()接受 ,因此不能同时调用它们。这只是当前的 Rust 无法(据我所知)表达这种模式。FnMut
0赞 Jmb 10/28/2022
@ChayimFriedman 好点,这不需要 ,只需要 .MutexRefCell