用子切片参考覆盖切片参考时出现错误

时间:2018-08-26 13:10:13

标签: rust

我正在尝试确定所有权规则。我要:

  • 从对切片的可变引用开始
  • 对其内容进行一些编辑
  • 将切片引用减少为子切片的引用,然后重复

以下是我的尝试:

pub fn example() {
    // Make a mutable slice
    let mut v = [0, 1, 2, 3];

    // Make a mutable reference to said slice
    let mut v_ref = &mut v[..];

    while v_ref.len() > 1 {
        // Involves some edits -> need mut
        v_ref.swap(0, v_ref.len() - 1);

        // Try to reduce slice to sub-slice (some simplification here)
        // Errors!
        let (v_l, v_h) = v.split_at_mut(v.len() / 2);
        v_ref = v_l;
    }
}

但是我遇到了错误:

error[E0502]: cannot borrow `*v_ref` as immutable because it is also borrowed as mutable
  --> src/lib.rs:11:23
   |
11 |         v_ref.swap(0, v_ref.len() - 1);
   |         -----         ^^^^^          - mutable borrow ends here
   |         |             |
   |         |             immutable borrow occurs here
   |         mutable borrow occurs here

error[E0499]: cannot borrow `v` as mutable more than once at a time
  --> src/lib.rs:15:26
   |
7  |     let mut v_ref = &mut v[..];
   |                          - first mutable borrow occurs here
...
15 |         let (v_l, v_h) = v.split_at_mut(v.len() / 2);
   |                          ^ second mutable borrow occurs here
...
18 | }
   | - first borrow ends here

error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
  --> src/lib.rs:15:41
   |
7  |     let mut v_ref = &mut v[..];
   |                          - mutable borrow occurs here
...
15 |         let (v_l, v_h) = v.split_at_mut(v.len() / 2);
   |                                         ^ immutable borrow occurs here
...
18 | }
   | - mutable borrow ends here

我知道您不能在同一范围内对单个对象进行多次引用。

应该有一种减小切片范围的安全方法,因为您只是在减小当前可变引用的范围。最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

问题1:可变且不变地使用相同的变量

Peter Hall points out一样,即使您不再关心v,代码也会尝试对变量v_ref进行并发可变引用。 MCVE:

pub fn example() {
    let mut v = 0;
    let mut v_ref = &mut v;
    println!("{}", v)
}

另请参阅:

问题2:可变且不变地使用相同的变量

然后,代码尝试在单个函数调用中重叠可变和可变借位。 MCVE:

pub fn example() {
    let mut v = [0, 1, 2, 3];
    v.split_at_mut(v.len());
}

另请参阅:

问题3:可变且可变地使用相同的变量

然后,该代码在循环中有重叠的v可变借位。

另请参阅:


一起:

pub fn example() {
    let mut v = [0, 1, 2, 3];
    let mut v_ref = &mut v[..];

    while v_ref.len() > 1 {
        let len = v_ref.len();
        v_ref.swap(0, len - 1);
        let (v_l, _) = { v_ref }.split_at_mut(len / 2);
        v_ref = v_l;
    }
}