尝试转移所有权时无法移出借用的内容
Cannot move out of borrowed content when trying to transfer ownership
我正在编写一个链表来围绕 Rust 生命周期、所有权和引用。我有以下代码:
pub struct LinkedList {
head: Option<Box<LinkedListNode>>,
}
pub struct LinkedListNode {
next: Option<Box<LinkedListNode>>,
}
impl LinkedList {
pub fn new() -> LinkedList {
LinkedList { head: None }
}
pub fn prepend_value(&mut self) {
let mut new_node = LinkedListNode { next: None };
match self.head {
Some(ref head) => new_node.next = Some(*head),
None => new_node.next = None,
};
self.head = Some(Box::new(new_node));
}
}
fn main() {}
但我收到以下编译错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:18:52
|
18 | Some(ref head) => new_node.next = Some(*head),
| ^^^^^ cannot move out of borrowed content
较新版本的 Rust 有一个稍微不同的错误:
error[E0507]: cannot move out of `*head` which is behind a shared reference
--> src/main.rs:18:52
|
18 | Some(ref head) => new_node.next = Some(*head),
| ^^^^^ move occurs because `*head` has type `std::boxed::Box<LinkedListNode>`, which does not implement the `Copy` trait
我在想 head
节点当前必须属于 self
,这是链表。当我将它分配给 new_node.next
时,可能会发生所有权变更。
我宁愿尽可能不克隆该值,因为这看起来很浪费。我不想在函数执行期间只 "borrow" 它。我真的很想转让它的所有权。
我该怎么做?
我已经看过 cannot move out of borrowed content when unwrapping a member variable in a &mut self method and 。
我尝试按照其中一个问题的已接受答案中的建议移除匹配臂,并在创建新 LinkedListNode
时定义 next
,但我收到相同的错误消息。
我已经成功添加了一个 append
方法,它需要一个 LinkedListNode
添加到列表的末尾。
Cannot move out of borrowed content when trying to transfer ownership
在高层次上,这对 Rust 来说是不合常理的。您无法转让所借物品的所有权 因为您不拥有它 。你不应该借我的车(&Car
) 然后把它给你在街上看到的第一个人!即使我把我的车借给你,让你改装,也是如此(&mut Car
)。
您根本无法将 head
移出 &self
,因为您无法改变该值。
您不能将 head
移出 &mut self
,因为这会使 LinkedList
结构处于不一致状态 - 其中一个字段将具有未定义的值。这是Rust安全保障的核心措施。
一般来说,您需要遵循 How can I swap in a new value for a field in a mutable reference to a structure? 中的内容来替换现有值。
在这种情况下,您可以使用Option::take
。这会将变量保留在原处,将其就地更改为 None
并返回先前的值。然后您可以使用该值来构建列表的新头部:
pub fn prepend_value(&mut self) {
let head = self.head.take();
self.head = Some(Box::new(LinkedListNode { next: head }));
}
一个更通用的解决方案是取得结构的所有权而不是借用它。这使您可以为所欲为。请注意,我们按值取 self
,而不是按引用:
pub fn prepend_value(mut self) -> LinkedList {
self.head = Some(Box::new(LinkedListNode { next: self.head }));
self
}
我正在编写一个链表来围绕 Rust 生命周期、所有权和引用。我有以下代码:
pub struct LinkedList {
head: Option<Box<LinkedListNode>>,
}
pub struct LinkedListNode {
next: Option<Box<LinkedListNode>>,
}
impl LinkedList {
pub fn new() -> LinkedList {
LinkedList { head: None }
}
pub fn prepend_value(&mut self) {
let mut new_node = LinkedListNode { next: None };
match self.head {
Some(ref head) => new_node.next = Some(*head),
None => new_node.next = None,
};
self.head = Some(Box::new(new_node));
}
}
fn main() {}
但我收到以下编译错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:18:52
|
18 | Some(ref head) => new_node.next = Some(*head),
| ^^^^^ cannot move out of borrowed content
较新版本的 Rust 有一个稍微不同的错误:
error[E0507]: cannot move out of `*head` which is behind a shared reference
--> src/main.rs:18:52
|
18 | Some(ref head) => new_node.next = Some(*head),
| ^^^^^ move occurs because `*head` has type `std::boxed::Box<LinkedListNode>`, which does not implement the `Copy` trait
我在想 head
节点当前必须属于 self
,这是链表。当我将它分配给 new_node.next
时,可能会发生所有权变更。
我宁愿尽可能不克隆该值,因为这看起来很浪费。我不想在函数执行期间只 "borrow" 它。我真的很想转让它的所有权。
我该怎么做?
我已经看过 cannot move out of borrowed content when unwrapping a member variable in a &mut self method and
我尝试按照其中一个问题的已接受答案中的建议移除匹配臂,并在创建新 LinkedListNode
时定义 next
,但我收到相同的错误消息。
我已经成功添加了一个 append
方法,它需要一个 LinkedListNode
添加到列表的末尾。
Cannot move out of borrowed content when trying to transfer ownership
在高层次上,这对 Rust 来说是不合常理的。您无法转让所借物品的所有权 因为您不拥有它 。你不应该借我的车(&Car
) 然后把它给你在街上看到的第一个人!即使我把我的车借给你,让你改装,也是如此(&mut Car
)。
您根本无法将 head
移出 &self
,因为您无法改变该值。
您不能将 head
移出 &mut self
,因为这会使 LinkedList
结构处于不一致状态 - 其中一个字段将具有未定义的值。这是Rust安全保障的核心措施。
一般来说,您需要遵循 How can I swap in a new value for a field in a mutable reference to a structure? 中的内容来替换现有值。
在这种情况下,您可以使用Option::take
。这会将变量保留在原处,将其就地更改为 None
并返回先前的值。然后您可以使用该值来构建列表的新头部:
pub fn prepend_value(&mut self) {
let head = self.head.take();
self.head = Some(Box::new(LinkedListNode { next: head }));
}
一个更通用的解决方案是取得结构的所有权而不是借用它。这使您可以为所欲为。请注意,我们按值取 self
,而不是按引用:
pub fn prepend_value(mut self) -> LinkedList {
self.head = Some(Box::new(LinkedListNode { next: self.head }));
self
}