How to work with two mutable slices of an array of Rust?

I have a function that should work on two parts of the same array. The goal is to be able to compose the #[nostd] , which can return a variable slice of a larger array to the caller and insert the remainder of the array for future distributions.

Here is an example of failed code:

 fn split<'a>(mut item: &'a mut [i32], place: usize) -> (&'a mut [i32], &'a mut [i32]) { (&mut item[0..place], &mut item[place..]) } fn main() { let mut mem: [i32; 2048] = [1; 2048]; let (mut array0, mut array1) = split(&mut mem[..], 768); array0[0] = 4; println!("{:?} {:?}", array0[0], array1[0]); } 

the error is this:

 error[E0499]: cannot borrow `*item` as mutable more than once at a time --> src/main.rs:2:32 | 2 | (&mut item[0..place], &mut item[place..]) | ---- ^^^^ second mutable borrow occurs here | | | first mutable borrow occurs here 3 | } | - first borrow ends here 

This template can also be useful for quick sorting in place, etc.

Is there anything unsafe about having two mutable references to non-overlapping fragments of the same array? If there is no way in pure rust, is there a "safe" unsafe spell that will allow it to continue?

+3
source share
2 answers

Is there anything unsafe about having two mutable references to non-overlapping fragments of the same array?

No, but a system like Rust currently cannot detect that you accept mutable references to two non-overlapping parts of a slice. Since this is a common use case, Rust provides a safe function to do exactly what you want: std::slice::split_at_mut .

fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one &mut into two with an index.

The first will contain all the indices from [0, mid) (excluding the mid index), and the second will contain all the indices from [mid, len) (excluding the len index itself).

+10
source

End Code:

 fn main() { let mut mem : [i32; 2048] = [1; 2048]; let (mut array0, mut array1) = mem[..].split_at_mut(768); array0[0] = 4; println!("{:?} {:?}", array0[0], array1[0]); } 

Wow, that was perfect. Thanks for finding this!

+1
source

All Articles