`在构建一个排序的链表时不能移出`&mut`-pointer`的解引用 [英] `cannot move out of dereference of `&mut`-pointer` while building a sorted linked list

查看:18
本文介绍了`在构建一个排序的链表时不能移出`&mut`-pointer`的解引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我正在学习 Rust 并决定构建一个排序的链表.一切看起来都不错,直到我到达 add 方法,这是代码:

So, I'm learning Rust and decided to build a sorted linked list. Everything looks nice until I reach the add method, here's the code:

struct NodeItem<'a, V:'a + Ord> {
  value : V,
  next : Box<Option<NodeItem<'a,V>>> // '
}

impl <'a, V:'a + Ord> NodeItem<'a,V> { // '

  fn new(value : V) -> NodeItem<'a,V> { // '
    NodeItem { value : value, next : box None }
  }

  fn add(&mut self, value : V) {

    match self.value.cmp(&value) {
      Less => {
        self.next = box Some(NodeItem {value: self.value, next : self.next });
        self.value = value;
      },
      Equal | Greater => {
        match *self.next {
          Some(ref mut next) => next.add(value),
          None => self.next = box Some(NodeItem::new(value)),
        }
      },
    }

  }

}

编译器抱怨:

/home/mauricio/projects/rust/data_structures/src/lists/mod.rs:16:47: 16:51 error: cannot move out of dereference of `&mut`-pointer
/home/mauricio/projects/rust/data_structures/src/lists/mod.rs:16         self.next = box Some(NodeItem {value: self.value, next : self.next });
                                                                                                               ^~~~
/home/mauricio/projects/rust/data_structures/src/lists/mod.rs:16:66: 16:70 error: cannot move out of dereference of `&mut`-pointer
/home/mauricio/projects/rust/data_structures/src/lists/mod.rs:16         self.next = box Some(NodeItem {value: self.value, next : self.next });

这里到底有什么问题?我知道我正在将引用移到其他地方,但生命周期参数不应该显示这些项目具有相关的生命"吗?

What is exactly the problem here? I understand that I am moving a reference somewhere else, but shouldn't the lifetime parameters show that these items have a related "life"?

这是从 21/12/14 开始使用 nightly.

This is using the nightly from 21/12/14.

推荐答案

这是一个类似的例子:

enum E { Hello }
struct A(E);

fn main() {
    let mut a = A(E::Hello);
    let b = &mut a;
    let c = b.0;
}

和错误:

<anon>:7:13: 7:14 error: cannot move out of dereference of `&mut`-pointer
<anon>:7     let c = b.0;
                     ^
<anon>:7:9: 7:10 note: attempting to move value to here
<anon>:7     let c = b.0;
                 ^
<anon>:7:9: 7:10 help: to prevent the move, use `ref c` or `ref mut c` to capture value by reference
<anon>:7     let c = b.0;
                 ^

请注意,编译器会告诉您如何防止这种情况下的错误.

Note that the compiler tells you how to prevent the error in this case.

问题是你的 self.value 不是 复制可以.这意味着当您分配它时,您将移出NodeItem(self),从而使其不再完全定义!这将是一件坏事,所以 Rust 会阻止你这样做.

The problem is that your self.value is not Copyable. That means that when you assign it, you are moving it out of the NodeItem (self), thus leaving it no longer fully defined! This would be a bad thing, so Rust prevents you from doing it.

您必须决定解决问题的正确方法是什么.最简单的方法是确保 T 是可复制的(或者可能是 克隆可以,具体取决于您的数据).但是,您可能想到处复制您的数据.我会调查更改您的代码以防止复制节点并仅更新条目.您可能需要使用类似 swap.

You have to decide what the right way of fixing your problem is. The easiest is to ensure that T is copyable (or maybe Cloneable, depending on your data). However, you probably don't want to be copying your data all around. I would investigate changing your code to prevent copying the node around and just updating entries. You may need to use something like swap.

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

impl<T> Node<T> {
    fn new(v: T) -> Node<T> { Node { v: v, next: None } }

    fn push_front(self, head: T) -> Node<T> {
        Node {
            v: head,
            next: Some(Box::new(self)),
        }
    }

    fn push_back(&mut self, tail: T) {
        match self.next {
            Some(ref mut next) => next.push_back(tail), 
            None => self.next = Some(Box::new(Node::new(tail))),
        }
    }

    fn push_after(&mut self, v: T) {
        let old_next = self.next.take();

        let new_next = Node {
            v: v,
            next: old_next,
        };

        self.next = Some(Box::new(new_next));
    }
}

fn main() {
    let mut n = Node::new(2u8);
    n.push_back(3u8);
    let mut n = n.push_front(0u8);
    n.push_after(1u8);

    println!("{:?}", n);
}

这篇关于`在构建一个排序的链表时不能移出`&amp;mut`-pointer`的解引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆