Ошибки в перезаписи ссылки на срез со ссылкой на подрежим - PullRequest
0 голосов
/ 26 августа 2018

Я пытаюсь закрепить правила владения. Я хочу:

  • начать с изменяемой ссылки на фрагмент
  • внести некоторые изменения в его содержимое
  • уменьшить ссылку на слайс до ссылки на суб-слайс и повторить

Ниже моя попытка:

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 голосов
/ 26 августа 2018

Проблема 1: использование той же переменной изменчиво и неизменно

Как и Питер Холл указывает на , код пытается ссылаться на переменную v, в то время как существует параллельная изменяемая ссылка на нее,даже если вас больше не волнует v_ref.A 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...