如何操作Rust数组的2个可变片?

hel*_*atv 4 lifetime slice rust

我有一个需要在单个阵列的两个部分上运行的功能.目的是能够构建一个#[nostd]分配器,该分配器可以将更大数组的变量片返回给调用者,并挂起到数组的其余部分以供将来分配.

这是失败的示例代码:

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]);
}
Run Code Online (Sandbox Code Playgroud)

错误如下:

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
Run Code Online (Sandbox Code Playgroud)

这种模式也可以用于就地快速排序等.

对同一个数组的非重叠切片有两个可变引用有什么不安全的吗?如果在纯锈中没有办法,是否有一个"安全"的unsafe咒语可以让它继续下去?

Dog*_*ert 13

对同一个数组的非重叠切片有两个可变引用有什么不安全的吗?

没有,但Rust的类型系统当前无法检测到您正在对片的两个非重叠部分进行可变引用.由于这是一个常见的用例,Rust提供了一个安全的功能来完全按照您的意愿执行操作:std::slice::split_at_mut.

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

&mut在索引处将一分为二.

第一个将包含所有索引[0, mid)(不包括索引 mid本身),第二个将包含所有索引[mid, len) (不包括索引len本身).

  • [一个显示如何使用它的简单操场](https://play.rust-lang.org/?gist=f40ec2e627267bd62b4a&version=stable) (2认同)