struct Ctx;
enum Callback {
Fn(fn(&mut Ctx)),
Boxed(Box<dyn FnOnce(&mut Ctx)>),
}
fn normal_fn(_: &mut Ctx) {}
let closure_no_capture = |_: &mut Ctx| {};
let closure_with_capture = {
let data = vec![];
move |_: &mut Ctx| drop(data)
};
// is it possible to write `impl From` for this?
fn with_cb(cb: impl Into<Callback>) {}
with_cb(normal_fn);
with_cb(closure_no_capture);
with_cb(closure_with_capture);
This is a wall of code. Do you have a question?
The question is in the comment. I did the following, but because of conflicting implementations I couldn't add another impl that makes use of the Fn
variant.
impl<F: FnOnce(&mut Ctx) + 'static> From<F> for Callback {
fn from(f: F) -> Self {
Callback::Boxed(Box::new(f))
}
}
Well that shows that the design is flawed. There's no need for the enum whatsoever. Function pointers implement Fn*()
traits by themselves.
OP should simply be using Box<dyn FnMut(...)>
for storing the function. (For fn items and non-capturing closures, the Self
type will be zero-sized, so the Box won't allocate, there won't be overhead.)
Thanks alot.
Because closure_with_capture
only implements FnOnce
, I wasn't able to use FnMut
.
I'm guessing the question is about how to avoid boxing when passing a regular fn
, and you answered that.
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.