Closure as FnMut input parameter


Hi all,

I’m new to Rust and while working my way through, I’ve come across something I don’t understand.

// A function which takes a closure as an argument and calls
// it. The closure takes no input and returns nothing.
fn apply<F>(f: F) where
    F: FnMut() {
    // ^ TODO: Try changing this to 'Fn' or 'FnMut'.


// A function which takes a closure and returns an 'i32'.
fn apply_to_3<F>(f: F) -> i32 where
    // The closure takes an 'i32' and returns an 'i32'.
    F: Fn(i32) -> i32 {


fn main() {
    let greeting = "hello";
    // A non-copy type.
    let mut farewell = "goodbye".to_owned();

    // Capture 2 variables: 'greeting' by reference and
    // 'farewell' by value.
    let diary = || {
        // 'greeting' is by reference: requires 'Fn'.
        println!("I said {}.", greeting);

        // Mutation forces 'farewell' to be captured by
        // mutable reference. Now requires 'FnMut'.
        println!("Then I screamed {}.", farewell);
        println!("Now I can sleep. zzzzz");

        // Manually calling drop forces 'farewell' to
        // be captured by value. Now requires 'FnOnce'.

    // Call the function which applies the closure.

    let double = |x| 2 * x;

    println!("3 doubled: {}", apply_to_3(double));
error: cannot borrow immutable local variable `f` as mutable

I commented out the drop, so the closure is of type FnMut and changed the annotation from FnOnce to FnMut. What am I missing?


To call a FnMut closure, f must be mutable. Use apply<F>(mut f: F) to make the f parameter mutable.


Thanks, that works. I thought I’d tried that, but apparently not.

It seems odd to require this syntax, as f is a reference to the closure which isn’t being mutated. The FnMut trait annotation says variables within the closure will be captured by mutable reference or by immutable reference.


The closure is basically a struct of function pointer and the closed-over values. Thus to change the environment, you have to be able to mutate that struct.

Another way to see this: Calling the closure is conceptually the same as calling the method


of this trait, which has a &mut self parameter [1].

[1] note, to actually use that syntax at the moment you’ll have to use nightly and a few annotations.