How can I split ownership of array elements?

Hi.

The following code is ok.

fn main() {
    let mut x = [1,2,3];
    let y = [4,5,6];
    for (a, b) in x.iter_mut().zip(&y) {
        *a += *b;
    }
}

But the following code is error.

fn main() {
    let mut x = [[1,2,3], [4,5,6]];
    for (a, b) in x[0].iter_mut().zip(&x[1]) {
        *a += *b;
    }
}

I understand the reason, but actually I often encounter such a situation.
If I use index loop, I can write equivalent code but if possible, I want to avoid it and want to write more functional programming style.

Are there any manners?

You can use split_at_mut:

fn main() {
    let mut x = [[1,2,3], [4,5,6]];
    let (aa, bb) =  x.split_at_mut(1);
    for (a, b) in aa[0].iter_mut().zip(&bb[0]) {
        *a += *b;
    }
}

Once we get slice patterns, you should be able to do this:

#![feature(slice_patterns)]
fn main() {
    let mut x = [[1,2,3], [4,5,6]];
    let &mut [ref mut aa, ref mut bb] =  &mut x;
    for (a, b) in aa.iter_mut().zip(bb) {
        *a += *b;
    }
}

Wow! Thank you!

I must study primitive types more.

Is it also possible to pick up only one element as mut and refer rest as &?

Slice pattern:

#![feature(slice_patterns)]
fn main() {
    let mut x = [[1,2,3], [4,5,6]];
    let &mut [ref mut aa, ref bb] =  &mut x;
    for (a, b) in aa.iter_mut().zip(bb) {
        *a += *b;
    }
}

You can also do this with iterators:

fn main() {
    let mut x = [[1,2,3], [4,5,6]];
    let mut iter = x.iter_mut();
    let (aa, bb) = match (iter.next(), iter.next()) {
        (Some(&mut ref mut aa), Some(&mut ref bb)) => (aa, bb),
        _ => panic!(),
    };
    // or:
    // let (&mut ref mut aa, &mut ref bb) = (iter.next().unwrap(), iter.next().unwrap());
    for (a, b) in aa.iter_mut().zip(bb) {
        *a += *b;
    }
}

Unfortunately, I can't get split_at_mut to work (it's claiming that the pattern is refutable)...

1 Like

Thank you for your great help!

I will think of my pattern.

I had no idea that was possible. That's really useful.

2 posts were split to a new topic: Split string array