Understanding Iter with FnMut

Since Iter’s "all" fn takes type FnMut is it possible to update the element while checking for condition and short circuiting? Though I understand it is not supposed to, but what prevents it from updating the value?

fn main() {
   let a = ["as", "zz"];

    let mut iter = a.iter();
    iter.all(|& (mut x)| {x = "cc"; true});

    for z in a.iter(){
        println!("{z}");
    }
}

Above prints

as
zz

In above case why setting "x = cc" not work?
Or Alternatively why does Iter "all" method takes F of type FnMut and not Fn when it is not supposed to mutate but only validate for condition

>Solution :

x = "cc" does not change the value referred by x, instead it changes the reference itself (i.e. it makes it refer to another value), as evidenced by this example:

fn main() {
   let a = ["as", "zz"];

    let mut iter = a.iter();
    iter.all(|&(mut x)| {
        println!("before: {:?}", x as *const _);
        x = "cc";
        println!("after: {:?}", x as *const _); 
        true});

    for z in a.iter(){
        println!("{z}");
    }
}

Playground

Note that this has nothing to do with the fact that the closure is FnMut, which only means that it may change any captured values as in:

fn main() {
   let a = ["as", "zz"];

    let mut count = 0;
    let mut iter = a.iter();
    iter.all(|&_x| {
        count += 1;    // This is possible because the closure is `FnMut`
        true});
    println!("Count: {count}");
    
    for z in a.iter(){
        println!("{z}");
    }
}

Playground

Leave a Reply