Hi everyone, i am working on tokio application where i need to pass a struct in to the stream fold , that struct contains a closures and/or pointers to the functions (depends). I have tried many different approaches and could not pass compiler errors like live times and so on.
I have created Gist code example of how i would like it to work (it is just and example and i would really like to get rid of Boxes and make it look nicer). Unfortunately it does not work any way (with or without Boxes)
I would really appreciate if someone helps me with this issue and explains why i it should be that way as i have spend last 3 days trying to resolve and could not do that. Thank you very much
Futures don't execute in the place where they're written. They will execute somewhere else, in the future, long after all your variables, all your function calls, are gone.
Until async/await lands, you can't use references anywhere in futures.
Put move on all closures used in futures.
Make sure things can actually be moved, i.e. no types with & or <'a> or Ref. Box and Arc are fine.
You have TWO FnMut's nested. One in for_each, and other in fold. That means the inner closure is not just one closure, it's many closures, each created for every run of for_each.
So it means that your one variable is trying to be moved into foldmany times, for each for_each call.
The solution is two wrap it in Arc, and then in for_each do:
let myFns = Arc::clone(&myFns);
so that each copy of fold's closure can have its own copy of myFns.
Thanks for helping, after adding Arc i still can not call any functions which are inside of myFns variable. I have created another gist with Arc added:
Thank you very much for you help seems like it works alright with as_ref and but now i am getting slightly different error i believe it is related to the Send and Sync traits on future, after calling a closure i am getting error on tokio::spawn that it can not send returned future and i have type mismatch.
Instead of Box<Future<Item = String, Error = ()>> + Send + Sync> i am getting just Box<Future<Item = String, Error = ()>>> type. How do you attach Send and Sync to the boxed future ?
Run rustup component add cargo-fix and cargo fix --edition
add edition = "2018" to your Cargo toml,
run cargo fix --edition-idioms
When you're working with an abstract type like dyn Trait, you get only what you ask for, and nothing more. Even if actual types you use it with support extra properties like Send/Sync, Rust pretends they don't exist, because you didn't ask for them to be guaranteed.
So to guarantee that every boxed future you could get is Send + Sync, you have to explicitly ask for it: