Mutate a value over an IterMut implementation

I am following the @kornel guide that is really great about different ways to implement linked list.

I am trying to test a mutation iterator and change a value while browsing the iterator. But I have a compilation issue

My test :

#[test]
    fn iter_mut_with_modification() {
        let mut list = List::new();

        list.push(1);
        list.push(2);
        list.push(3);

        /* for element in list.iter_mut() {
            *element +=10;
        } */

        //list.iter_mut().for_each(|element| *element += 10);

        let mut iterator = list.iter_mut();
        
        if let Some( & mut elem ) = iterator.next() {
            *elem = 100;
        }

        let mut iterator = list.iter();

        assert_eq!(iterator.next(), Some(&100));
    }

The error

$ cargo test
...
error[E0614]: type `{integer}` cannot be dereferenced                    ] 0/4: lists_rs, lists_rs
   --> src\second_bis.rs:201:13
    |
201 |             *elem = 100;
    |             ^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0614`.
error: Could not compile `lists_rs`.
warning: build failed, waiting for other jobs to finish...
error: build failed

Please advise. The whole playground is here

1 Like

The iterator yields &mut T which you are already dereferencing in the pattern match Some(&mut elem) = iterator.next(). Just do Some(elem) instead.

You can think of pattern matching quite literally. Let's assume the iterator yields Some(&mut 5):

let Some(&mut elem) =
              ^^^^
    Some(&mut  5  )              => elem is 5

let Some(elem  ) =
         ^^^^^^
    Some(&mut 5)                 => elem is &mut 5
1 Like

BTW, I just linked to the guide. I'm not the author of it.

As for the reference problem, in Rust the patterns (left side of =) are "backwards".

These are the same:

let ptr = &1;
let ref ptr = 1;

and these are the same:

let &num = &1;
let num = 1;
1 Like