Mutable chaining of iterators

I am confused by iterator chaining. This works fine:

#[derive(Debug)]
struct T (isize);

fn main() {
    let v1 = vec![T(0),T(1),T(2),T(3)];
    let v2 = vec![T(4),T(5),T(6),T(7)];

    for i in v1.iter().chain(v2.iter()) {
        println!("{:?}", i);
    }
}

Now imagine I want to change the values in v1 and v2. This works okay.

#[derive(Debug)]
struct T (isize);

fn main() {
    let mut v1 = vec![T(0),T(1),T(2),T(3)];
    let mut v2 = vec![T(4),T(5),T(6),T(7)];

    for mut i in &mut v1 {
        i.0 = i.0 + 1;
    }

    for mut i in &mut v2 {
        i.0 = i.0 + 1;
    }


    for i in v1.iter().chain(v2.iter()) {
        println!("{:?}", i);
    }
}

But, obviously, it's a bit duplicative. But I have not been able to
get this working with chaining. Consider this:

#[derive(Debug)]
struct T (isize);

fn main() {
    let mut v1 = vec![T(0),T(1),T(2),T(3)];
    let mut v2 = vec![T(4),T(5),T(6),T(7)];

    for i in &mut v1.iter().chain(v2.iter()) {
        i.0 = i.0 + 1;
    }

    for i in v1.iter().chain(v2.iter()) {
        println!("{:?}", i);
    }
}

This gives me the error message:

8 |     for i in &mut v1.iter().chain(v2.iter()) {
  |              ------------------------------- help: consider changing this to be a mutable reference: `&mut mut v1.iter().chain(v2.iter())`
9 |         i.0 = i.0 + 1;
  |         ^^^^^^^^^^^^^ `i` is a `&` reference, so the data it refers to cannot be written

The suggested alternative syntax (&mut mut) is illegal. So, I think
I am missing something here; is this possible and what is the right
syntax?

You can use iter_mut instead of iter

for i in v1.iter_mut().chain(v2.iter_mut()) {
    i.0 = i.0 + 1;
}
2 Likes

Thank you very much! I thought that there was a simple answer.