I would like to implement a trait for FnOnce
but I get an error that I don't understand:
pub trait Something{}
pub trait MyTrait {
fn do_it<E: Something>(&self, smt: &mut E);
}
impl<F> MyTrait for F
where
F: FnOnce(&mut dyn Something),
{
fn do_it<E: Something>(&self, smt: &mut E) {
(self)(smt)
}
}
The compiler complains that:
error[E0507]: cannot move out of `*self` which is behind a shared reference
--> src/my_test.rs:26:9
|
26 | (self)(smt)
| ^^^^^^ move occurs because `*self` has type `F`, which does not implement the `Copy` trait
If I replace FnOnce
with Fn
then it works, but I need it for FnOnce
.
Any way to make it work?
You need to either: consume self
by value (not by shared reference)
pub trait Something{}
pub trait MyTrait {
fn do_it<E: Something>(self, smt: &mut E);
}
impl<F> MyTrait for F
where
F: FnOnce(&mut dyn Something),
{
fn do_it<E: Something>(self, smt: &mut E) {
(self)(smt)
}
}
or change the bounds from FnOnce
to Fn
pub trait Something{}
pub trait MyTrait {
fn do_it<E: Something>(&self, smt: &mut E);
}
impl<F> MyTrait for F
where
F: Fn(&mut dyn Something),
{
fn do_it<E: Something>(&self, smt: &mut E) {
(self)(smt)
}
}
This is because FnOnce
needs to consume the value in order to call the closure, whereas Fn
only needs a shared reference in order to call the closure.
system
Closed
June 17, 2020, 5:44pm
3
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.