5

Is there any way I can clone values for the async move closures for futures::stream?

I'm using future's for_each_concurrent

My code is something like this:

async fn foo() {
    use futures::stream::{self, StreamExt};

    let a: String = String::new();

    let stream = stream::once(async { 42 });

    stream
        .for_each_concurrent(None, |stream_item| async move {
            println!("{}", a);
            println!("{}", stream_item);
        })
        .await;
}

The error here:

error[E0507]: cannot move out of `a`, a captured variable in an `FnMut` closure
  --> src/main.rs:9:61
   |
4  |       let a: String = String::new();
   |           - captured outer variable
...
9  |           .for_each_concurrent(None, |stream_item| async move {
   |  _____________________________________________________________^
10 | |             println!("{}", a);
   | |                            -
   | |                            |
   | |                            move occurs because `a` has type `String`, which does not implement the `Copy` trait
   | |                            move occurs due to use in generator
11 | |             println!("{}", stream_item);
12 | |         })
   | |_________^ move out of `a` occurs here

I have to use move because of this:

error[E0373]: async block may outlive the current function, but it borrows `stream_item`, which is owned by the current function
  --> src/main.rs:9:56
   |
9  |           .for_each_concurrent(None, |stream_item| async {
   |  ________________________________________________________^
10 | |             println!("{}", a);
11 | |             println!("{}", stream_item);
   | |                            ----------- `stream_item` is borrowed here
12 | |         })
   | |_________^ may outlive borrowed value `stream_item`

If it was a loop I'd just clone as in each iteration, and move those clones inside a closure, is there a way to do something like this here?

0

1 Answer 1

15

You can simply clone a before the async move block:

stream
    .for_each_concurrent(None, |stream_item| {
        let a = a.clone();
        async move {
            println!("{}", a);
            println!("{}", stream_item);
        }
    })
    .await;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.