0
pub fn sort_by_key<K, F>(&mut self, mut f: F)
where
    F: FnMut(&T) -> K,
    K: Ord,
{
    merge_sort(self, |a, b| f(a).lt(&f(b)));
}

Here FnMut takes an immutable reference &T, what does it mean?

Isn't FnMut supposed to take a mutable reference &mut T?

user3698446
  • 107
  • 6

1 Answers1

2

No, a FnMut means this function may use a mutable reference to a caputred variable. For example, take this function:

let mut x = 5;
{
    let mut square_x = || x *= x;
    square_x();
}
assert_eq!(x, 25);

This function takes no arguments. Certainly no immutable arguments. Yet it's considered a FnMut because it captures the mutable reference to x and mutates. it.

Note that Fn is a subtype of FnMut. Thus, any function that takes a FnMut can also be passed a function that does not mutate state. In this case, |a, b| f(a).lt(&f(b)) is just a Fn. It can be called multiple times and mutates no state. But any Fn is also a valid FnMut and any FnMut or Fn is also a valid FnOnce.

This does mean Fn can take a mutable reference as a parameter, so this is valid:

let b:Box<dyn Fn(&mut u8)->()> = Box::new(|a|*a+=1);

This function uses a mutable reference yet it's a Fn not a FnMut since it doesn't capture any variables.

See also this question for a lot more details

mousetail
  • 7,009
  • 4
  • 25
  • 45