rust FnMut接受一个不可变的引用意味着什么?

z8dt9xmd  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(164)
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)));
}

这里FnMut取一个不可变的引用&T,它是什么意思?
FnMut不是应该接受一个可变的引用&mut T吗?

ldfqzlk8

ldfqzlk81#

不,FnMut意味着这个函数 * 可能 * 使用一个对捕获变量的可变引用。

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

这个函数没有参数,当然也没有不可变的参数,但它被认为是FnMut,因为它捕获了对x的可变引用,并对. it进行了变异。
请注意,FnFnMut的子类型。因此,任何接受FnMut的函数也可以被传递一个不改变状态的函数。在这种情况下,|a, b| f(a).lt(&f(b))只是一个Fn,它可以被多次调用,并且不改变任何状态。但是,任何Fn也是有效的FnMut,任何FnMutFn也是有效的FnOnce
这并不意味着Fn可以将可变引用作为参数,因此这是有效的:

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

这个函数使用了一个可变的引用,但是它是一个Fn而不是FnMut,因为它没有捕获任何变量。
See also this question for a lot more details

相关问题