从单链表中删除一个节点有错误“不能搬出借来的内容”(Deleting a node from sin

2019-11-04 22:27发布

我想提出一个单向链表。 当你删除一个节点,前一节点的next应该成为当前节点的nextprev->next = curr->next; ),并返回data ,如果该指数相匹配。 否则,先前的节点成为当前节点和电流节点变为下一个节点( prev = curr; curr = curr->next; ):

struct Node<T> {
    data: T,
    next: Option<Box<Node<T>>>,
}

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

impl LinkedList<i64> {
    fn remove(&mut self, index: usize) -> i64 {
        if self.len() == 0 {
            panic!("LinkedList is empty!");
        }
        if index >= self.len() {
            panic!("Index out of range: {}", index);
        }
        let mut count = 0;
        let mut head = &self.head;
        let mut prev: Option<Box<Node<i64>>> = None;
        loop {
            match head {
                None => {
                    panic!("LinkedList is empty!");
                }
                Some(c) => {
                    // I have borrowed here
                    if count == index {
                        match prev {
                            Some(ref p) => {
                                p.next = c.next;
                                //       ^ cannot move out of borrowed content
                            }
                            _ => continue,
                        }
                        return c.data;
                    } else {
                        count += 1;
                        head = &c.next;
                        prev = Some(*c);
                        //          ^^ cannot move out of borrowed content
                    }
                }
            }
        }
    }

    fn len(&self) -> usize {
        unimplemented!()
    }
}

fn main() {}
error[E0594]: cannot assign to field `p.next` of immutable binding
  --> src/main.rs:31:33
   |
30 |                             Some(ref p) => {
   |                                  ----- consider changing this to `ref mut p`
31 |                                 p.next = c.next;
   |                                 ^^^^^^^^^^^^^^^ cannot mutably borrow field of immutable binding

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:31:42
   |
31 |                                 p.next = c.next;
   |                                          ^ cannot move out of borrowed content

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:40:37
   |
40 |                         prev = Some(*c);
   |                                     ^^ cannot move out of borrowed content

游乐场链接获取更多信息。

我怎样才能做到这一点? 是我的方法不对?

Answer 1:

在开始之前,请阅读学习锈就太多了链表 。 人们认为,因为他们已经被教导他们,要么不,如果你介绍的内存不安全或照顾完全从程序员带走代理语言链表很容易

锈既不,这意味着你要想想你可能从来没有想到过的事情。


有许多与你的代码的问题。 你问,“不能搬出借来的内容”的一个是由许多其他问题早已覆盖,所以没有理由重申所有这些很好的答案:

  • 不能搬出借来的内容
  • 试图转移所有权时,无法移动借内容的出
  • 错误[E0507]:不能搬出借来的内容

TL; DR:您正在试图移动的所有权next从出一个参考的; 你不能。

p.next = c.next; 

您正试图修改一个不变的参考:

let mut head = &self.head; 

你允许人们以去除一个过去的结束,这没有任何意义对我说:

if index >= self.len() 

您遍历整个树不是一次,而是一次迭代前两次执行删除操作:

 if self.len() == 0 if index >= self.len() 

所有这一切都在比较的事实,你的算法是在鲁斯特的眼睛,因为你试图引入可变混叠瑕疵相形见绌。 如果你的代码能够编译,你就会有一个可变引用previous还有一个可变的参考current 。 但是,你可以得到一个可变的参考currentprevious 。 这将允许你打破锈病的存储安全保证!

取而代之的是,你只能跟踪的current ,当右手食指被发现,分解并移动棋子:

fn remove(&mut self, index: usize) -> T {
    self.remove_x(index)
        .unwrap_or_else(|| panic!("index {} out of range", index))
}

fn remove_x(&mut self, mut index: usize) -> Option<T> {
    let mut head = &mut self.head;

    while index > 0 {
        head = match { head }.as_mut() {
            Some(n) => &mut n.next,
            None => return None,
        };
        index -= 1;
    }

    match head.take().map(|x| *x) {
        Some(Node { data, next }) => {
            *head = next;
            Some(data)
        }
        None => None,
    }
}

也可以看看:

  • 无法获取遍历的递归结构时,可变参考:不能借一次作为可变更多的时间
  • 我如何获得一个拥有价值了`Box`的?

游乐场链接获取更多信息。

有许多问题,你的代码的其余部分,如事实,你的结果insert方法是不同于任何我曾经见过。

我怎么会写 。



文章来源: Deleting a node from singly linked list has the error “cannot move out of borrowed content”