Can you help me out with opaquer & future issue.
Here is the code
Unable to understand what is wrong.
Thank you
Can you help me out with opaquer & future issue.
Here is the code
Unable to understand what is wrong.
Thank you
One problem is that the functions/callbacks f1
, f2
do not implement Fn(usize)
. They would if they were declared as regular fn
, but since they are async fn
their actual return types are anonymous futures—nameless types that implement Future<Output = ()>
, because async fn f(args: Args) -> Ret { /* body */ }
expands to[1]
fn f(args: Args) -> impl Future<Output = Ret> {
async { /* body */ }
}
This means that f1
cannot be coerced to dyn Fn(usize)
, not even behind an indirection. To store type-erased async callbacks in a Vec
, you'll need to erase the return types too, like this:
use futures::future::BoxFuture;
struct Store {
callbacks: Vec<Box<dyn Fn(usize) -> BoxFuture<'static, ()> + Send + Sync + 'static>>,
}
impl Store {
fn add<Fut, F>(&mut self, cb: F)
where
Fut: Future<Output = ()> + Send + 'static,
F: Fn(usize) -> Fut + Send + Sync + 'static,
{
self.callbacks.push(Box::new(move |x| Box::pin(cb(x))));
}
}
async fn f1(u: usize) {
println!("Hello {}", u);
}
fn main() {
let mut store = Store { callbacks: Vec::new() };
store.add(f1);
}
With that changed, it's straightforward to make your Store::run
code work. Note that you don't need to wrap the callbacks in Arc<Mutex<...>>
unless you plan to clone the Store
and you're actually using FnMut
callbacks rather than Fn
as in your playground. If you don't need to clone the Store
, Box<...>
is enough[2], and if you do need to clone the Store
but don't need FnMut
, then Arc<...>
is enough. Working playground.
well, almost: the compiler-generated "expansion" also includes information about what auto traits and lifetime bounds are satisfied by the returned Future
↩︎
or Mutex<Box<...>>
if you have FnMut
callbacks but need Store::run
to take &self
rather than &mut self
, though in this situation you might also consider using a Mutex<Vec<...>>
to collect the callbacks and plain Box<...>
for each individual callback ↩︎
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.