首页 > 解决方案 > 从单个链表中删除重复项

问题描述

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
}

上面的代码删除了自定义单链表中的重复项。(例如 [1,1,2] -> [1,2])
使用 (2) 和 (4) 编译并执行程序应该执行的操作。
(1) 和 (3) 产生编译器错误,我无法理解这里发生了什么。

标签: rust

解决方案


我创建了一个可重现的游乐场。其他人,如果我的答案有误,请使用它来帮助和纠正我。

对于 (1),当您调用 时cur.unwrap(),值 ( Option<&mut Box<ListNode>>) 从 移动cur。但是当你打电话时cur.as_mut(),它给了你一个Option<&mut &mut Box<ListNode>>,并且打开它不会移动它cur的价值。我创建了一个小操场代码片段来说明这一点。

对于(3),它有两个错误。

  1. 当您调用时cur.as_ref(),该值位于 a 后面&,因此您无法访问它的值,但在您调用时再次将其作为可变值借用as_mut()

  2. 如果将as_ref()(3) 中的调用替换为as_mut()调用,则只会看到另一个错误。

    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
    

    您不能先借用cur的值,cur用新值重新分配,然后再使用借来的值。游乐场来说明这一点。

对于(4),是的,它消耗cur的是 的值,是 a Option<&mut Box<ListNode>>,不是Option<Box<ListNode>>,所以没关系。


推荐阅读