`在构建排序链表时无法移出`&mut`-pointer`的取消引用
`cannot move out of dereference of `&mut`-pointer` while building a sorted linked list
所以,我正在学习 Rust 并决定构建一个排序链表。在我到达 add 方法之前一切看起来都不错,这里是代码:
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 });
这里到底有什么问题?我知道我正在将引用移动到其他地方,但是生命周期参数不应该显示这些项目有相关的 "life"?
这是从 2014 年 12 月 21 日开始的每晚使用。
这是一个similar example:
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;
^
请注意,编译器会告诉您如何避免这种情况下的错误。
问题是您的 self.value
不是 Copy
able。这意味着当您分配它时,您将 将其移出 NodeItem
(self
),从而使其不再完全定义!这将是一件坏事,因此 Rust 会阻止您这样做。
您必须决定解决问题的正确方法是什么。最简单的方法是确保 T
是可复制的(或者 Clone
able, 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);
}
所以,我正在学习 Rust 并决定构建一个排序链表。在我到达 add 方法之前一切看起来都不错,这里是代码:
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 });
这里到底有什么问题?我知道我正在将引用移动到其他地方,但是生命周期参数不应该显示这些项目有相关的 "life"?
这是从 2014 年 12 月 21 日开始的每晚使用。
这是一个similar example:
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;
^
请注意,编译器会告诉您如何避免这种情况下的错误。
问题是您的 self.value
不是 Copy
able。这意味着当您分配它时,您将 将其移出 NodeItem
(self
),从而使其不再完全定义!这将是一件坏事,因此 Rust 会阻止您这样做。
您必须决定解决问题的正确方法是什么。最简单的方法是确保 T
是可复制的(或者 Clone
able, 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);
}