Reputation: 141
pub fn delete_duplicates(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut head = head;
let mut cur = head.as_mut();
while cur.is_some() && cur.as_ref().unwrap().next.is_some() {
if cur.as_ref().unwrap().val == cur.as_ref().unwrap().next.as_ref().unwrap().val {
//let next = cur.unwrap().next.as_mut().unwrap().next.take(); (1) Error!
let next = cur.as_mut().unwrap().next.as_mut().unwrap().next.take(); // (2) Ok
cur.as_mut().unwrap().next = next;
}
else {
//cur = cur.as_ref().unwrap().next.as_mut(); (3) Error!
cur = cur.unwrap().next.as_mut(); // (4) Ok
}
}
head
}
The code above deletes duplicates inside a custom single linked list. (e.g. [1,1,2] -> [1,2])
Using (2) and (4) compiles and does what the program is supposed to do.
(1) and (3) generate compiler error and I just can't grasp what is happening here.
as_mut()
? I believe cur is already mutable.as_ref()
when assigning a value to lvalue?Upvotes: 1
Views: 123
Reputation: 1792
I have created a reproducible playground. Other folks, please use it to help and correct me if my answer is wrong.
For (1), when you call cur.unwrap()
, the value (Option<&mut Box<ListNode>>
) got moved from cur
. but when you call cur.as_mut()
, it gave you a Option<&mut &mut Box<ListNode>>
, and unwrapping it doesn't move cur
's value. I created a small playground code snippet to illustrate this.
For (3), it has two errors.
when you call cur.as_ref()
, the value is behind a &
, so you cannot access its value but then borrowed it as mutable again when you call as_mut()
if you replace the as_ref()
call in (3) with a as_mut()
call, you will see only the other error.
Line 28, Char 17: cannot assign to `cur` because it is borrowed (solution.rs)
|
28 | cur = cur.as_mut().unwrap().next.as_mut();
| ^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | borrow of `cur` occurs here
| assignment to borrowed `cur` occurs here
| borrow later used here
error: aborting due to previous error
You cannot first borrow cur
's value, reassign cur
with a new value, then use the borrowed value. Playground to illustrate this.
For (4), yes, it consumes cur
's value, which is a Option<&mut Box<ListNode>>
, not Option<Box<ListNode>>
, so it is OK.
Upvotes: 2