Map field in Recursive struct to a Vector

Hi,

I have the following struct:

#[derive(Debug, Clone)]
pub struct Node {
    pub parent: Option<Rc<Node>>,
    pub position: Position,
}

And I want to create a Vector of the struct field Position, so node -> Vec.

For that I have the following:

let mut path = HashSet::new();
let mut current_node = Rc::new(exit_node);
while current_node.parent != None {
    let parent = current_node.parent.expect("");
    path.insert(parent.position.clone());
    current_node = parent;
}

This is the compiling output:

27 |         let parent = current_node.parent.expect("");
   |                      ^^^^^^^^^^^^^^^^^^^
   |                      |
   |                      move occurs because value has type `std::option::Option<std::rc::Rc<algorithms::Node>>`, which does not implement the `Copy` trait
   |                      help: consider borrowing the `Option`'s content: `current_node.parent.as_ref()`

But it isn't working, any hint?

Without seeing the compiler output, it’s hard to know for sure, but I expect it’s complaining about you moving position out of the struct. Try

path.push(current_node.position.clone());

(You may need to add #[derive(Clone)] to the definition of Position)

I edited with the compile output. The problem is with Option<Rc>, the cloning of Position struct is ok.

Have you tried replacing current_node.parent.expect("") with current_node.parent.as_ref().expect("") on the problematic line?

Instead of:

while x != None {
   x.unwrap()
}

it's more idiomatic (and potentially slightly faster) to write:

while let Some(x) = x {
}

As for expect/unwrap complaining about move: unwrapping is a self-destruct operation for the Option. If you don't own the option, you can't destroy it.

There's as_ref() and as_deref() that flips a borrowed option inside-out, so instead of a borrowed option of an owned value, you get to own option of a borrowed value. This lets you unwrap and destroy the Option.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.