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

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

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实例只复制一次。

#[derive(Debug)]
#[allow(dead_code)]
struct Parent {
    id: usize,
    children: Vec<Child>,
}

#[derive(Debug)]
#[allow(dead_code)]
struct Child {
    id: usize,
    age: usize,
}

fn main() {
    let mut parents: Vec<Parent> = Vec::new();

    for parent_id in 1..4 {
        let mut p = Parent {
            id: parent_id,
            children: Vec::new(),
        };

        // 如果在这里将其推送到Vector,父项的值就会被移动,
        // 并且在下面的子项循环中对`p`的修改将不会传递到外部循环。
        parents.push(p);

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

        // 将推送移到这里可以解决问题,但感觉不太对,必须这样做。
        //parents.push(p);
    }

    println!("{:#?}", parents);
}

错误:

error[E0382]: borrow of moved value: `p`
  --> src/main.rs:34:13
   |
19 |         let mut p = Parent {
   |             ----- move occurs because `p` has type `Parent`, which does not implement the `Copy` trait
...
27 |         parents.push(p);
   |                      - value moved here
...
34 |             p.children.push(c);
   |             ^^^^^^^^^^^^^^^^^^ 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.

#[derive(Debug)]
#[allow(dead_code)]
struct Parent {
    id: usize,
    children: Vec&lt;Child&gt;,
}

#[derive(Debug)]
#[allow(dead_code)]
struct Child {
    id: usize,
    age: usize,
}

fn main() {
    let mut parents: Vec&lt;Parent&gt; = Vec::new();

    for parent_id in 1..4 {
        let mut p = Parent {
            id: parent_id,
            children: Vec::new(),
        };

        // If pushed to the vector here, the Parent value is moved
        // and the modifications to `p` in the child loop below are
        // not seen past the outer loop.
        parents.push(p);

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

        // Moving the push to here works but it doesn&#39;t
        // feel right having to do this.
        //parents.push(p);
    }

    println!(&quot;{:#?}&quot;, parents);
}

Error:

error[E0382]: borrow of moved value: `p`
  --&gt; src/main.rs:34:13
   |
19 |         let mut p = Parent {
   |             ----- move occurs because `p` has type `Parent`, which does not implement the `Copy` trait
...
27 |         parents.push(p);
   |                      - value moved here
...
34 |             p.children.push(c);
   |             ^^^^^^^^^^^^^^^^^^ 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);
}


<details>
<summary>英文:</summary>

You can either push the parent after you&#39;re done with it, or you can access it via the `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);
}

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:

确定