如何在嵌套循环中使用向量和引用?

huangapple go评论97阅读模式
英文:

How to use vectors and references in nested loops?

问题

我正在尝试使用Rust中的Structs和Vectors来实现父子关系。我遇到的问题是,当我创建一个新的父实例并将其推送到Vector时,它的值会被移动到该Vector中。

在将父项推送到Vector之后尝试添加子项会导致所有权问题。如果将父项推迟到添加子项之后,这个问题就不会发生。

下面链接的Rust播放器是我尝试做的简单示例。实际上,层次结构中还会有另外两个级别(父 -> 子 -> 孙子 -> 曾孙子)。

我尝试使用Box<Parent> 来使用引用并将盒装父项推送到Vec<Box<Parent>>,但是同样的问题会发生,因为引用会被复制,但Parent 没有实现Copy trait。

我想每个Struct实例只复制一次。

  1. #[derive(Debug)]
  2. #[allow(dead_code)]
  3. struct Parent {
  4. id: usize,
  5. children: Vec<Child>,
  6. }
  7. #[derive(Debug)]
  8. #[allow(dead_code)]
  9. struct Child {
  10. id: usize,
  11. age: usize,
  12. }
  13. fn main() {
  14. let mut parents: Vec<Parent> = Vec::new();
  15. for parent_id in 1..4 {
  16. let mut p = Parent {
  17. id: parent_id,
  18. children: Vec::new(),
  19. };
  20. // 如果在这里将其推送到Vector,父项的值就会被移动,
  21. // 并且在下面的子项循环中对`p`的修改将不会传递到外部循环。
  22. parents.push(p);
  23. for child_id in 1..3 {
  24. let c = Child {
  25. id: child_id,
  26. age: child_id + 10,
  27. };
  28. p.children.push(c);
  29. }
  30. // 将推送移到这里可以解决问题,但感觉不太对,必须这样做。
  31. //parents.push(p);
  32. }
  33. println!("{:#?}", parents);
  34. }

错误:

  1. error[E0382]: borrow of moved value: `p`
  2. --> src/main.rs:34:13
  3. |
  4. 19 | let mut p = Parent {
  5. | ----- move occurs because `p` has type `Parent`, which does not implement the `Copy` trait
  6. ...
  7. 27 | parents.push(p);
  8. | - value moved here
  9. ...
  10. 34 | p.children.push(c);
  11. | ^^^^^^^^^^^^^^^^^^ value borrowed here after move

Playground

英文:

I'm trying to implement a parent-child relationship using Structs and Vectors in Rust. The issue I'm having is that when I create a new parent instance and push it to a vector, its value is moved to that vector.

Attempting to add children after pushing the parent into a vector causes an ownership issue. If the parent push is delayed until after adding children this problem doesn't occur.

The Rust playground linked below is a simple example of what I'm trying to do. In reality, there will be another two levels of the hierarchy (parent -> child -> grandchild -> great grandchild).

I've tried using Box&lt;Parent&gt; in an attempt to use references and pushing the boxed parent to a Vec&lt;Box&lt;Parent&gt;&gt; but the same problem occurs where the reference would be copied, but Parent doesn't implement the Copy trait.

I'd like to have one copy of each Struct instance only.

  1. #[derive(Debug)]
  2. #[allow(dead_code)]
  3. struct Parent {
  4. id: usize,
  5. children: Vec&lt;Child&gt;,
  6. }
  7. #[derive(Debug)]
  8. #[allow(dead_code)]
  9. struct Child {
  10. id: usize,
  11. age: usize,
  12. }
  13. fn main() {
  14. let mut parents: Vec&lt;Parent&gt; = Vec::new();
  15. for parent_id in 1..4 {
  16. let mut p = Parent {
  17. id: parent_id,
  18. children: Vec::new(),
  19. };
  20. // If pushed to the vector here, the Parent value is moved
  21. // and the modifications to `p` in the child loop below are
  22. // not seen past the outer loop.
  23. parents.push(p);
  24. for child_id in 1..3 {
  25. let c = Child {
  26. id: child_id,
  27. age: child_id + 10,
  28. };
  29. p.children.push(c);
  30. }
  31. // Moving the push to here works but it doesn&#39;t
  32. // feel right having to do this.
  33. //parents.push(p);
  34. }
  35. println!(&quot;{:#?}&quot;, parents);
  36. }

Error:

  1. error[E0382]: borrow of moved value: `p`
  2. --&gt; src/main.rs:34:13
  3. |
  4. 19 | let mut p = Parent {
  5. | ----- move occurs because `p` has type `Parent`, which does not implement the `Copy` trait
  6. ...
  7. 27 | parents.push(p);
  8. | - value moved here
  9. ...
  10. 34 | p.children.push(c);
  11. | ^^^^^^^^^^^^^^^^^^ value borrowed here after move

Playground

答案1

得分: 1

你可以在完成后将父项推送到它,或者可以通过 Vec 访问它:```rust
parents.push(p);

let p = parents.last_mut().unwrap();
for child_id in 1..3 {
let c = Child {
id: child_id,
age: child_id + 10,
};
p.children.push(c);
}

  1. <details>
  2. <summary>英文:</summary>
  3. You can either push the parent after you&#39;re done with it, or you can access it via the `Vec`:
  4. ```rust
  5. parents.push(p);
  6. let p = parents.last_mut().unwrap();
  7. for child_id in 1..3 {
  8. let c = Child {
  9. id: child_id,
  10. age: child_id + 10,
  11. };
  12. p.children.push(c);
  13. }

huangapple
  • 本文由 发表于 2023年7月4日 22:37:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613716.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定