某事告诉我如何实现链接列表:
InetAddress.getHostAddress()
当我想使用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
来更改list
变量本身:
prepend
这是我想出的一种实现,但这是不对的:
list.prepend(1);
错误是:
fn my_prepend(&mut self, elem: u32) {
*self = Cons(elem, Box::new(*self));
}
答案 0 :(得分:6)
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);
}