gpt4 book ai didi

rust - 变量所有权在迭代之间如何工作?

转载 作者:行者123 更新时间:2023-12-03 11:30:31 25 4
gpt4 key购买 nike

我试图学习使用rust ,并想到将链接列表作为实践问题来理解所有权/借用概念,并且遇到了困难。pushLinkedList方法应按以下方式工作:

t = 0 | root: None | push 5
t = 1 | root: { value: 5, next: None } | push 6
t = 2 | root: { value: 5, next: { value: 6, None } } |
这是尝试执行相同操作的代码:
#[derive(Debug, Clone)]
struct Node {
value: u32,
next: Option<Box<Node>>,
}

impl Node {
fn new(value: u32) -> Node {
Node { value, next: None }
}
}

#[derive(Debug, Clone)]
struct LinkedList {
root: Option<Box<Node>>,
}

impl LinkedList {
fn new(node: Option<Box<Node>>) -> LinkedList {
LinkedList { root: node }
}

fn push(self, node: Option<Box<Node>>) {
let maybe_node = self.root;

loop {
match maybe_node {
Some(tail_node) => { // use of moved value. std::boxed::Box<Node> doesn't implement copy trait. --- (1)
if tail_node.next.is_none() {
tail_node.next = node; // tail_node is not mutable. --- (2)
break;
};
}
_ => (),
}
}
}
}

fn main() {
let mut node = Node::new(0);
let linked_list = LinkedList::new(Some(Box::new(node)));

for number in 1..5 {
node = Node::new(number);
linked_list.push(Some(Box::new(node))); // move occurs. Value moved here in a previous iteration --- (3)
}
println!("{:?}", linked_list);
}
我不明白“移动发生”错误(1、3),我不清楚值移到哪里了?似乎是迭代导致所有权发生变化,但我看不出怎么做。
另外,错误(2)我的实现是最好的方法吗?

最佳答案

在Rust中,有两种方式处理所有权,即移动语义或借用语义。这是一些了解它的规则。
第一条规则是每个数据块只能同时拥有一个所有者。如果将某个变量分配给其他变量,则可以有效地移动数据,并且数据将由新所有者拥有。
第二条规则是,如果您拥有某些数据,该数据归某人所有,但您想读取它,则可以借用它。借阅本质上是获取对数据的引用,该数据由其他人拥有。
现在回到您的问题。在函数声明中,您已将第一个参数声明为self


fn push(self, node: Option<Box<Node>>) {
let maybe_node = self.root;

loop {
match maybe_node {
Some(tail_node) => { // use of moved value. std::boxed::Box<Node> doesn't implement copy trait. --- (1)
if tail_node.next.is_none() {
tail_node.next = node; // tail_node is not mutable. --- (2)
break;
};
}
_ => (),
}
}
}
从本质上讲,这意味着在调用函数时,您将获取自我的所有权,因此使任何先前的所有者无效。循环中发生的事情是,在第一次迭代中,该值被移入了函数,并且不再由 linked_list拥有。在第二次迭代中,您再次尝试访问数据,但是它不再有效,因为它已被移到函数中。
为了规避您的问题,您将需要声明您的函数,如下所示:
 fn push(&mut self, node: Option<Box<Node>>) {
let maybe_node = self.root;

loop {
match maybe_node {
Some(tail_node) => { // use of moved value. std::boxed::Box<Node> doesn't implement copy trait. --- (1)
if tail_node.next.is_none() {
tail_node.next = node; // tail_node is not mutable. --- (2)
break;
};
}
_ => (),
}
}
}
在上面的声明中,您说的是您正在借用 self,并且希望对其进行更改(这就是我们拥有 &mut而不是 &的原因)。
有关更多详细信息,请引用 chapter about ownership in Rust book

关于rust - 变量所有权在迭代之间如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65493710/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com