Rust:如何在流适配器中使用一个值而不克隆它两次

0 rust rust-tokio

目前,当我的流收到新值时,我尝试打印计数器值:


fn add_counter_to_stream<T: std::marker::Send + 'static>(
    stream: PinnedStream<T>,
) -> PinnedStream<T> {
    let counter = Arc::new(Mutex::new(0)); // Shared counter between threads
    futures::StreamExt::boxed(stream.map({
        let counter = Arc::clone(&counter);
        move |value| {
            let counter = Arc::clone(&counter);
            async move {
                // Print counter value and increment
                let mut num = counter.lock().await;
                println!("Counter: {}", *num);
                *num += 1;
            };
            value
        }
    }))
}
Run Code Online (Sandbox Code Playgroud)

Arc::clone(&counter)然而,如上所示,除非我创建两个嵌套闭包并使用两次,否则代码不会编译。有没有一种方法可以重构它,以便在一个克隆操作中完成,为什么在这个示例中我需要两个闭包?

cdh*_*wie 5

你这个有点想多了。

您所需要的只是让映射函数拥有一个可变计数器。使用的映射函数StreamExt::map不返回未来,而是返回一个值。这意味着您不必担心未来会捕获计数器的生命周期。

您可以在不使用Arc和不使用以下命令的情况下执行此操作Mutex

fn add_counter_to_stream<T: std::marker::Send + 'static>(
    stream: PinnedStream<T>,
) -> PinnedStream<T> {
    let mut counter = 0;

    stream
        .map(move |value| {
            println!("Counter: {}", counter);
            counter += 1;
            value
        })
        .boxed()
}
Run Code Online (Sandbox Code Playgroud)

请注意,这里没有单独的线程,因为映射函数是在从流中提取项目时串行运行的。