我刚开始学习Rust编程,并阅读了Rust书籍中的闭包章节。书中提到sort_by_key
函数需要FnMut
类型的闭包,但是我想知道如果sort_by_key
函数捕获的项没有被闭包改变,为什么不能将其改为Fn
类型?
我刚开始学习Rust编程,并阅读了Rust书籍中的闭包章节。书中提到sort_by_key
函数需要FnMut
类型的闭包,但是我想知道如果sort_by_key
函数捕获的项没有被闭包改变,为什么不能将其改为Fn
类型?
FnMut
是Fn
的超级特性。这意味着任何Fn
的实例都可以在期望FnMut
的地方使用。
也许可以通过下面这个来自FnMut
文档的示例来解释一下:
fn do_twice<F>(mut func: F)
where F: FnMut()
{
func();
func();
}
fn main() {
let mut x: usize = 1;
{
let add_two_to_x = || x += 2;
do_twice(add_two_to_x);
let print_stuff = || println!("Awesome!");
do_twice(print_stuff);
}
println!("{x}");
}
add_two_to_x
需要 FnMut
才能工作,而不能使用 Fn
,而print_stuff
则两者都可以使用。FnMut
时(作为使用者),您有自由设计一个可以修改其环境的闭包,但并非必须这样做。而使用 Fn
时则会更加受限制。FnMut
是 Fn
的超集,但是 sort_by_key
的闭包似乎并没有改变它的环境,这清楚地表明它根本不需要 FnMut
。 - Haris Muzaffarsort_by_key
接受 FnMut
,这意味着如果需要,您可以传递一个修改该闭包捕获环境的闭包。 - PitaJsort_by_key
中传递一个会改变捕获值的闭包吗?对我来说,这看起来像是一种代码异味,更合理的做法是防止这种情况发生,但也许有一些我没有考虑到的合法用例。 - undefined
FnMut
不会改变其参数,而是会改变其捕获的环境。因此,它可以接受比Fn
更多的闭包函数。 - Aleksander KrauzeFnOnce
无法工作,因为sort_by_key
需要调用闭包不止一次。这就使得FnMut
成为最灵活的选择。 - PitaJFn
不起作用,但是你的评论解释了为什么FnOnce
不起作用,显然这是行不通的。 - Haris MuzaffarFnMut
不会改变其参数,而是改变其捕获的环境时,它的闭包如何改变其捕获环境?换句话说,sort_by_key
的闭包如何改变其捕获环境? - Haris Muzaffar