Passing immutable reference to a slice while iterating over it as mutable

Hi,

Maybe it's too late, but I cannot find an easy way to solve this stupid problem.
I have this code:

struct Foo;

impl Foo {
    fn update(&mut self, _foos: &[Foo]){
         // Do some stuff on self comparing _other_ foos
    }
}

fn main() {
    let mut foos: Vec<Foo> = vec![];
    
    for f in &mut foos{
        f.update(&foos);
    }
}

It is not compiling, fair enough (I mean I am violating one fundamental rule, I know :blush:)... But which would be an idiomatic way to manage this situation?

Do you need the whole of foos in the slice?

Are your Foos Copy?

Lending iterator style that could be adapted to return only the suffix or only the prefix.

If so you could use Cells. (There's no Copy bound in the playground, but you need it for Cell::get, or maybe you can use Cell::take if Foo: Default.)


And there are some other safe approaches, or you could use raw references. But having a &mut Foo aliased by some other simultaneously usable reference or way of accessing the data is UB no matter what.

1 Like

The whole apart from the current one on which I am calling the update method

They are not Copy

You could manually split the others from the index you're updating: playground

    for i in 0..foos.len() {
        // Note: this if-let pattern will never fail in practice
        if let (head, [f, tail @ ..]) = foos.split_at_mut(i) {
            f.update_slices(head, tail);
            f.update_iter(head.iter().chain(&*tail));
        }
    }
5 Likes