При решении проблемы с кодом 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, верно?
Кроме того, я не уверен, связана ли другая ошибка спервый.