如果参数是按值取的,为什么还要使用`FnMut`?

qed*_*qed 5 closures rust

这是Rust by Example 的一个例子:

pub trait Iterator {
    // The type being iterated over.
    type Item;

    // `any` takes `&mut self` meaning the caller may be borrowed
    // and modified, but not consumed.
    fn any<F>(&mut self, f: F) -> bool where
        // `FnMut` meaning any captured variable may at most be
        // modified, not consumed. `Self::Item` states it takes
        // arguments to the closure by value.
        F: FnMut(Self::Item) -> bool {}
}
Run Code Online (Sandbox Code Playgroud)

FnMut如果参数是按值取的,为什么要费心使用,因为无论如何都不能改变参数?事实上,为什么FnMut甚至允许在这里?似乎只FnOnce 允许这样做

已经注意到 Rust 选择如何在没有注释的情况下动态捕获变量。这在正常使用中非常方便,但是在编写函数时,这种歧义是不允许的。必须注释闭包的完整类型,包括哪个捕获类型。闭包使用的捕获方式被注释为以下之一trait

  • Fn: 按引用捕获 ( &T)
  • FnMut: 通过可变引用进行捕获 ( &mut T)
  • FnOnce: 按值捕获 ( T)

sta*_*lue 8

FnOnceFnMut和之间的区别在于Fn函数如何访问其环境(分别为移动、可变引用、共享引用)。它与访问函数的参数无关。

FnMut这里需要,因为该any方法可能需要多次调用该函数。

Rust 书中一段关于闭包的实现。它显示了self参数的差异,它本质上是struct包含环境的。