Is FnOnce(&mut ... ) equals to FnMut( ... )?

When you see FnOnce, FnMut, and so on, they are referring to the mutability/reusability of the closure object itself, not the arguments that are passed through it.

It's basically all about the fact that closures can capture state from their environment. When you write code like this...

let x = 40;
let f = || x + 2;

...the closure acquires a regular reference to the data "x", so you get an Fn().

When you write code like this...

let mut x = 30;
let f = || { x += 12; };

...the closure now needs to modify its environment, so it acquires an &mut to x, and you get an FnMut().

Finally, when you do something like this...

let s = String::new("42");
let f = || s;

...the closure moves state out when it's called. So it needs to capture s by move and also output it by value. Which means that you can only safely call F once, because after that the internal "s" state has been trashed by moving it out. And thus, you get an FnOnce().

4 Likes