如何在不需要分配给新变量的情况下为链表实现前置?
How to implement prepend for a linked list without needing to assign to a new variable?
有人告诉我如何实现链表:
enum List {
Cons(u32, Box<List>),
Nil,
}
impl List {
fn prepend(self, elem: u32) -> List {
Cons(elem, Box::new(self))
}
}
当我想使用prepend
时,我需要做以下事情:
list = list.prepend(1);
但是,我想创建一个不需要每次都创建新变量的函数prepend
returns。我只想使用 prepend
:
更改 list
变量本身
list.prepend(1);
这是我想出的一种实现方式,但并不正确:
fn my_prepend(&mut self, elem: u32) {
*self = Cons(elem, Box::new(*self));
}
错误是:
error[E0507]: cannot move out of borrowed content
List::prepend
必须 移动 self
因为这确实是正在发生的事情。链表的新头是一个新对象,旧头移到堆上,使旧变量无效。
在 my_prepend
中,您有一个对 self
的可变引用,但随后您移动了它的值,因此 self
引用变得无效。尽管它只是暂时无效,但这就是消息 "cannot move out of borrowed content"
所抱怨的。
解决这个问题的一种方法是将 self
移出到一个变量中并 同时 将其替换为 Nil
,这样 self
引用永远不会无效。您可以使用 mem::replace
:
use std::mem;
fn my_prepend(&mut self, elem: u32) {
// Move the value of self into head, and leave self as Nil so it isn't invalid
let head = mem::replace(self, List::Nil);
// Reassign to self with the prepended value
*self = head.prepend(elem);
}
有人告诉我如何实现链表:
enum List {
Cons(u32, Box<List>),
Nil,
}
impl List {
fn prepend(self, elem: u32) -> List {
Cons(elem, Box::new(self))
}
}
当我想使用prepend
时,我需要做以下事情:
list = list.prepend(1);
但是,我想创建一个不需要每次都创建新变量的函数prepend
returns。我只想使用 prepend
:
list
变量本身
list.prepend(1);
这是我想出的一种实现方式,但并不正确:
fn my_prepend(&mut self, elem: u32) {
*self = Cons(elem, Box::new(*self));
}
错误是:
error[E0507]: cannot move out of borrowed content
List::prepend
必须 移动 self
因为这确实是正在发生的事情。链表的新头是一个新对象,旧头移到堆上,使旧变量无效。
在 my_prepend
中,您有一个对 self
的可变引用,但随后您移动了它的值,因此 self
引用变得无效。尽管它只是暂时无效,但这就是消息 "cannot move out of borrowed content"
所抱怨的。
解决这个问题的一种方法是将 self
移出到一个变量中并 同时 将其替换为 Nil
,这样 self
引用永远不会无效。您可以使用 mem::replace
:
use std::mem;
fn my_prepend(&mut self, elem: u32) {
// Move the value of self into head, and leave self as Nil so it isn't invalid
let head = mem::replace(self, List::Nil);
// Reassign to self with the prepended value
*self = head.prepend(elem);
}