An async function that receives an async callback which consumes it arguments
An async function that receives an synchronous callback which receives a reference (borrowing)
I couldn't implement:
Async function that receives an async callback which borrow it's arguments
I'm using a recursive walkdir as case of study, it receives a path to start, and a callback, it calls the callback for every file it founds, and recurse it in folders that it find .. is a good exercise and became complex fast
Here is the working code (synchronous callback)
And here is the not working code (async callback)
I tried that 'b lifetime parameter to say "Hey, &DirEntry will live as long as my returned Future, but it seems that this is not the case since, it won't compile, I now I'm stuck, again
Is what I'm trying to do, possible?
How can I express that "I have a callback that receives a reference and return a future and that the reference lives lesser than my outer function, but enough for the callback"?
In other words, how can I express lifetimes for Fn async callbacks parameters?
Sorry, when working with closures, it's not possible for the output to borrow from the input. The easiest option is to just not create a future that needs to borrow from the input, by first creating a value that has ownership and then moving it into the future instead:
walkdir(Path::new(".").as_ref(), |d: &DirEntry| {
let s = d.file_name().into_string().unwrap();
async move {
println!("{}", s);
}
}).await;
With "output", I am referring to the value of type Fut returned by your closure. I am saying that this returned value of type Fut is not able to borrow from the reference passed to the closure, because if it could, the closure would return a different type depending on which lifetime the reference you gave the closure has.
If Fut depends on &DirEntry, each possible reference lifetime would lead to a distinct Fut concrete type
Now lifetimes being generic types start to make some sense to me. When I say foo<'a>(bar: &'a) each application of 'a type leads is like a kind of type application (I'm ignoring elision here), so
let a = &1; { let b = &2; foo(&a); foo(&b); }
Is really like applying concrete types to a generic function, except that the compiler will do borrow checking instead of type checking, did I get it right?