The Iterator trait's method any
takes a parameter implementing FnMut trait.
Here's the definiton
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn any<F>(&mut self, f: F) -> bool
where
Self: Sized,
F: FnMut(Self::Item) -> bool,
{
#[inline]
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
move |(), x| {
if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
}
}
self.try_fold((), check(f)) == ControlFlow::BREAK
}
I think the rule of FnMut is: The closure captures variables by mutable reference.
But the following code goes wrong because of "use of moved value: rust
".
This means the variable rust
has been moved into the closure, which has conflicts with the rule of FnMut trait.
// Situation 1
let rust = String::from("rust");
let list: Vec<String> = vec![String::from("rust")];
list.into_iter().any(move |s| s == rust);
dbg!(rust); // error here
However, the following code is also refused by the compiler due to the rule of FnMut trait.
// Situation 2
let rust = String::from("rust");
let list: Vec<String> = vec![String::from("rust")];
list.into_iter().any(move |s| {
let temp = rust; // error here
s == temp
});
So my question is, why there are different behaviors about the FnMut trait between these two situations?
I think the second situation is easy to understand. But why in the first situation, the captured variable will be consumed?