0

The title should have already suggest you I have noticed How can I put an async function into a map in Rust? and I have failed to proceed my work. Here is my sample code based on above link:

extern crate async_std;
use async_std::task;
use std::future::Future;
use std::pin::Pin;
use std::boxed::Box;

type VarIn = &String;
type VarOut = String;
type FnType = Box< dyn Fn(VarIn) -> Pin<Box<dyn Future<Output=VarOut>>> >;

async fn test(v: FnType) {
    println!("{}", v("hi".to_string()).await)
}

async fn var(s: &String) -> String {
    format!("var:{}", s)
}

fn main() {
    task::block_on(test(Box::new(|s| Box::pin(var(s)))));
}

If VarIn is replaced by String instead of &String then everything is fine. However, my use case needs me to pass a reference instead to fulfill my usage (I use it in an infinite loop, so I can't pass the ownership to this function). What should I do to successfully pass the reference to async function, or there is some design to circumvent this?

orb
  • 175
  • 2
  • 13

1 Answers1

0

You have to specify in the type definitions that are used in the function test what the lifetime of the reference is and how it relates to the Future.

VarIn<'a> = &'a String;
VarOut = String;
FnType<'a> = Box<dyn Fn(VarIn<'a>) -> Pin<Box<dyn Future<Output=VarOut> + 'a>>>;

This won't ultimately work, because the String created in test will be dropped at the bottom of the function, while the &String will be returned with the Future. You can use an &str and get this example to work, and that is what I suggest.

VarIn<'a> = &'a str
VarOut = String
FnType<'a> = Box<dyn Fn(VarIn<'a>) -> Pin<Box<dyn Future<Output=VarOut> + 'a>>>;

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d86d8b57b556c3d4c4e0282f890a2228

Boyd Johnson
  • 342
  • 7
  • 11