在 Rust 中删除单向链表中的节点

Yjy*_*eff 7 linked-list rust data-structures

我是 Rust 的新手,想在 Rust 中编写链表以获得乐趣。我对如何删除链表中的节点感到困惑。这是我的简单代码。

#[derive(Debug)]
struct Node{
    v: usize,
    next: Option<Box<Node>>,
}

struct LinkedList {
    head: Option<Box<Node>>,
}

impl LinkedList {
    fn remove(&mut self, v: usize) -> Option<usize> {
        let mut current_node: &mut Option<Box<Node>> = &mut self.head;
        loop {
           match current_node {
                None => break,
                Some(node) => {
                    if node.v == v {
                        // current_node = what? 
                        // ???????????????
                        break;
                    } else {
                        current_node = &mut node.next;
                    }
                },
            };
        }

        match current_node.take().map(|x| *x) {
            Some(node) => {
                *current_node = node.next;
                return Some(node.v)
            },
            None => None,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这里是铁锈游乐场。我正在使用夜间版本和edition = 2018. 在循环中,我尝试找到下一个节点包含我搜索的值的节点。但是,我对在 ?? 中写什么感到困惑。位置。

Pet*_*all 5

没有真正的代码可以进入那个空间来修复它;你需要做一些更大的改变。

问题之一是您已经可变地借用了 中的当前节点current_node,但随后需要在该引用仍然存在时对其进行变异。

利用 2018 版中的非词法生命周期,您可以执行以下操作:

impl LinkedList {
    fn remove(&mut self, v: usize) -> Option<usize> {
        let mut current = &mut self.head;
        loop {
            match current {
                None => return None,
                Some(node) if node.v == v => {
                    *current = node.next.take();
                    return Some(v);
                },
                Some(node) => {
                    current = &mut node.next;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

不知何故,使用火柴守卫if node.v == v制作两个火柴臂,而不是使用if一个火柴臂内的条件,让借用者检查器推断这是安全的。我不确定为什么if不允许使用 match 分支内的语句 - 有些人认为这可能是一个错误