Soo*_*ner 2 move-semantics rust data-structures borrowing
有人告诉我如何实现链表:
enum List {
Cons(u32, Box<List>),
Nil,
}
impl List {
fn prepend(self, elem: u32) -> List {
Cons(elem, Box::new(self))
}
}
Run Code Online (Sandbox Code Playgroud)
当我想使用时prepend,我需要做以下事情:
list = list.prepend(1);
Run Code Online (Sandbox Code Playgroud)
但是,我想创建一个每次prepend返回时都不需要创建新变量的函数.我只想用以下方法更改list变量本身prepend:
list.prepend(1);
Run Code Online (Sandbox Code Playgroud)
这是我提出的一个实现,但它不对:
fn my_prepend(&mut self, elem: u32) {
*self = Cons(elem, Box::new(*self));
}
Run Code Online (Sandbox Code Playgroud)
错误是:
error[E0507]: cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
102 次 |
| 最近记录: |