async fn func(num: &mut usize) -> Result<String, _>
{
println!("func{}", num);
Ok("".to_string())
}
pub fn funcs<F>(func:F)
{
....
}
I know how to pass' fn ', but how to handle' fn ->Future 'with' asynchronous'
async fn func(num: &mut usize) -> Result<String, _>
{
println!("func{}", num);
Ok("".to_string())
}
pub fn funcs<F>(func:F)
{
....
}
I know how to pass' fn ', but how to handle' fn ->Future 'with' asynchronous'
Maybe this works for you:
use std::future::Future;
async fn func(num: &mut usize) -> Result<String, ()> {
println!("func{}", num);
Ok("".to_string())
}
pub fn funcs<'a, F, Fut>(_func: F)
where
F: Fn(&'a mut usize) -> Fut,
Fut: Future<Output = Result<String, ()>>,
{
}
fn main() {
funcs(func);
}
...
type PinFutureObjWithLife<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
pub type ItemWithLife = Box<dyn for<'a> Fn(&'a mut usize) -> PinFutureObjWithLife<'a, ()>>;
...
pub fn funcs<'a, F, Fut>(_func: F)
where
F: Fn(&'a mut usize) -> Fut,
Fut: Future<Output = Result<String, ()>>,
{
let mut vec = Vec::<ItemWithLife>::new();
vec.push(Box::new(|num| Box::pin(handle(num))));
}
I want to store the handle in vec
err:
borrowed data escapes outside of closure
argument requires that `'1` must outlive `'a`
What should I do?
Thank you.
You might be able to get a more satisfying answer if you could tell us exactly what you are after and provide us with a minimal reproducible example. I have no idea what you really want to achieve based on your snippet, nor can I reproduce the error you posted.
...
pub struct Llt {
router_map: Option<Vec<ItemWithLife>>,
}
impl Llt {
pub fn add_router<F, Fut>(&mut self,msg_id:usize,handle: F)
where
F: Fn(usize) -> Fut + Send + 'static,
Fut: Future<Output = WorkerResult>+ Send + 'static,
{
let mut vec = Vec::<ItemWithLife>::new();
vec.push(Box::new(|num| Box::pin(handle(num))));
self.router_map = vec;
}
}
pub fn build() -> Self {
Llt {
router_map: None,
}
}
...
type PinFutureObjWithLife<T> = Pin<Box<dyn Future<Output = T>>>;
pub type ItemWithLife = Box<dyn Fn(usize) -> PinFutureObjWithLife<WorkerResult>>;
...
async fn func(num:usize) -> WorkerResult
{
println!("func1_without_ref-{}", num);
Ok("".to_string())
}
pub type WorkerResult<T = String, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
...
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn it_works() {
let mut llt = Llt::build();
llt.add_router(1, func);
}
}
I want to customize a struct to store fn
, just like how axum and actix_web define a route
But Axum and Actix_web use some advanced macros, and I haven't learned anything about macros yet, as in the code above. I want to use this method to save fn
in my router_map
and retrieve it when needed
It's basically just missing a move
before the closure to make sure the handle
is captured by value:
use futures::future::{BoxFuture, Future};
pub struct Llt<'a> {
router_map: Vec<ItemWithLife<'a>>,
}
impl<'a> Llt<'a> {
pub fn add_router<F, Fut>(&mut self, handle: F)
where
F: Fn(usize) -> Fut + 'static,
Fut: Future<Output = WorkerResult> + Send + 'a,
{
self.router_map
.push(Box::new(move |num| Box::pin(handle(num))));
}
pub fn build() -> Self {
Llt {
router_map: Vec::new(),
}
}
}
pub type ItemWithLife<'a> = Box<dyn Fn(usize) -> BoxFuture<'a, WorkerResult>>;
pub type WorkerResult<T = String, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
#[cfg(test)]
mod tests {
use super::*;
async fn func(num: usize) -> WorkerResult {
println!("func1_without_ref-{}", num);
Ok("".to_string())
}
#[tokio::test]
async fn it_works() {
let mut llt = Llt::build();
llt.add_router(func);
}
}
It succeeded, thank you very much. Your personal homepage is great, and good luck to you