Rust "if let" vs "unwrap" behavior

408 Views Asked by At

I'm about a week into learning Rust, and I'm struggling to understand some of the nuances of ownership. I have this code that works:

if let Some(node) = current {
    node.next = Some(Box::new(ListNode::new(sum_digit)));
    current = node.next.as_mut();
}

I thought that if let Some(node) = current was equivalent to assigning node the value of current.unwrap(). However, the code below doesn't work:

current.unwrap().next = Some(Box::new(ListNode::new(sum_digit)));
current = current.unwrap().next.as_mut();

I receive the following error message:

46  |         let mut current = head.as_mut();
    |             ----------- move occurs because `current` has type `Option<&mut Box<ListNode>>`, which does not implement the `Copy` trait
...
73  |                 current.unwrap().next = Some(Box::new(ListNode::new(sum_digit)));
    |                         -------- `current` moved due to this method call
74  |                 current = current.unwrap().next.as_mut();
    |                           ^^^^^^^ value used here after move

Is there a way to accomplish the same thing without using if let? I know that current is not None, so that is safe.

1

There are 1 best solutions below

0
Masklinn On

I thought that if let Some(node) = current was equivalent to assigning node the value of current.unwrap().

current.unwrap() will unconditionally consume current. Thanks to match ergonomics if let doesn't have to do that.

Is there a way to accomplish the same thing without using if let? I know that current is not None, so that is safe.

current.as_mut().unwrap()? You're already using as_mut.

Option::as_mut will borrow the option, and create a new option with a reference to the contents of the existing one. You can consume that (by unwrapping) without affecting the original option.