Hi there, I have two questions about FnMut
and FnOnce
(which I realize are currently marked as unstable
)
I'm playing around with the FnMut
and FnOnce
traits, trying to implement them on a struct. Here's an example of what I first tried:
struct Handler {
call_count: u32
}
impl FnMut<()> for Handler {
extern "rust-call" fn call_mut(&mut self, args: ()) -> u32 {
println!("call_mut()");
self.call_count += 1;
self.call_count
}
}
Trying to compile this I get the following error: the trait 'core::ops::FnOnce<()>' is not implemented for the type 'Handler' [E0277]
. Reading the docs, it's clear that FnMut
requires an impl for FnOnce
, so my first question is: why is this the case?
In my example where I increment call_count
(thus requiring a mutable self
), I'm not actually able to provide a meaningful body to a fn call_once
. So just to get something to compile, the body of fn call_once
is just a panic!()
.
To test this, it's simple:
fn main() {
let mut h = Handler {call_count: 0};
h();
h();
h();
println!("call_count is {}", h.call_count);
}
This works as expected -- "call_mut()" is printed 3 times, and the call_count is set to 3 at the end.
To continue testing, I tried to create a non-mutable Handler
:
fn main() {
let h = Handler {call_count: 0};
h();
}
I had thought that since h
was immutable, the FnOnce
trait would be used. But this isn't the case, as rust give the following error:
a.rs:27:5: 27:6 error: cannot borrow immutable local variable `h` as mutable
a.rs:27 h();
So it looks like to implement FnMut
, I have to also implement FnOnce
, but there isn't an obvious way to call the FnOnce impl? This also confuses me.
I feel like I'm missing some key understanding about how these traits are designed. Please help
(Using rust nightly from f207ecbe0 playpen link: Rust Playground)
Thanks,
-Andrew