lemon
lemon

Reputation: 13

how to fix "cannot return value referencing function parameter 'x' returns a value referencing data owned by the current function" in the async rust?

I'm new to rust , I write some async code to send two request concurrently:

use std::time::Duration;
use futures::future::join_all;
use tokio::time::sleep;

// #[derive(Clone, Debug)]
pub struct Request {}

impl Request {
    pub async fn do_req(&self , num : i32) -> i32 {
        sleep(Duration::from_secs(1)).await;
        num * 2
    }
}

#[tokio::test]
async fn test() {
    let v = vec![Request{} , Request{}];

    let futs : Vec<_> = v.into_iter().map(|req|{
        req.do_req(1)
    }).collect();

    let res = join_all(futs).await;

    println!("{:?}", res);
}

but I get a error in the iterator "cannot return value referencing function parameter req returns a value referencing data owned by the current function" in the line "req.do_req(1)".

I consider req.do_req(1) return a new value so I can't understand why the error arise, it's very kind if someone can tell me how it is happened and how to fix it,thank you.

Upvotes: 1

Views: 765

Answers (1)

BallpointBen
BallpointBen

Reputation: 13750

The error message could be a bit more helpful. The fundamental issue is that you're trying to hold references to the elements of v — the reqs — but those elements don't exist anymore because you've consumed v (and therefore its elements) by calling v.into_iter(). What the compiler is trying to say is that in v.into_iter().map(|req| ...), req is an owned Request, but the Futures you're producing and collecting into futs hold references to that owned data. When map’s closure ends, req is dropped (because it's owned, because of into_iter()), and then those Futures would be holding dangling references, which the compiler rightly prevents.

If you replace this with v.iter(), it will work because the Futures you've collected now hold references to data that still exists; nothing has been consumed.

Upvotes: 2

Related Questions