«изменяемое заимствование начинается здесь в предыдущей итерации цикла» для задачи 83 Leetcode: удалить дубликаты из отсортированного списка - PullRequest
0 голосов
/ 13 октября 2019

При решении проблемы с кодом Leetcode 83 я столкнулся с двумя проблемами проверки заимствований. Вот проблемный фрагмент кода:

pub struct Solution {}

// Definition for singly-linked list.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
    pub val: i32,
    pub next: Option<Box<ListNode>>,
}

impl ListNode {
    #[inline]
    pub fn new(val: i32) -> Self {
        ListNode { next: None, val }
    }
}
impl Solution {
    pub fn delete_duplicates(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        if head.is_none() {
            return None;
        }
        let mut h = head;
        let mut p1 = h.as_mut().unwrap();

        while let Some(p2) = p1.next.as_mut() {
            if p1.val == p2.val {
                p1.next = p2.next.take();
            } else {
                p1 = p2; // error!!
                // p1 = p1.next.as_mut().unwrap(); // ok
            }
        }
        h
    }
}

Когда я непосредственно использую p1=p2 в предложении else, средство проверки заимствований жаловалось:

error[E0499]: cannot borrow `p1.next` as mutable more than once at a time
  --> src/q00083_remove_duplicates_from_sorted_list.rs:24:30
   |
24 |         while let Some(p2) = p1.next.as_mut() {
   |                              ^^^^^^^ mutable borrow starts here in previous iteration of loop

error[E0506]: cannot assign to `p1.next` because it is borrowed
  --> src/q00083_remove_duplicates_from_sorted_list.rs:26:17
   |
24 |         while let Some(p2) = p1.next.as_mut() {
   |                              ------- borrow of `p1.next` occurs here
25 |             if p1.val == p2.val {
26 |                 p1.next = p2.next.take();
   |                 ^^^^^^^
   |                 |
   |                 assignment to borrowed `p1.next` occurs here
   |                 borrow later used here

error: aborting due to 2 previous errors

Но оно компилируется, если я переключаюсь нарешение на следующей строке (т.е. закомментированная строка с // ok). Почему контролер заимствований считает, что p1.next будет заимствован несколько раз? Похоже, что для условий if и else p1.next должен каждый раз ссылаться на разные ListNode, верно?

Кроме того, я не уверен, связана ли другая ошибка спервый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...