Reputation: 107
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
?
Upvotes: 0
Views: 167
Reputation: 8010
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
Upvotes: 2