I am working on a project where I instantiate a parent struct, do some work based on the input, and build its child struct. In my implementation it contains metadata utilized for the parent struct's functionality, so I access the child struct immediately with unwrap
which causes a partial move of the parent's value, making it impossible to return. See the minimal example code:
pub struct ParentStruct {
child: Option<ChildStruct>
}
struct ChildStruct {
value: String
}
impl ParentStruct {
pub fn new() -> ParentStruct {
let mut parent = ParentStruct {
child: None
};
// After this, parent has child property
parent.build_child();
let child = parent.child.unwrap();
// Use child's values in some operation
println!("Printing child's value: {:?}", child.value);
// Reassigning child presumably "puts it back"--is this correct?
// parent.child = Some(child);
// Without previous line, this errors
parent
}
fn build_child(&mut self) {
let child = ChildStruct {
value: String::from("child created")
};
self.child = Some(child);
}
}
This causes the following error:
error[E0382]: use of partially moved value: `parent`
--> src/main.rs:52:9
|
43 | let child = parent.child.unwrap();
| -------- `parent.child` partially moved due to this method call
...
52 | parent
| ^^^^^^ value used here after partial move
|
note: this function takes ownership of the receiver `self`, which moves `parent.child`
--> /Users/way/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:383:25
|
383 | pub const fn unwrap(self) -> T {
| ^^^^
= note: partial move occurs because `parent.child` has type `Option<ChildStruct>`, which does not implement the `Copy` trait
As I note in the example code, I can assign Some(child)
back to parent.child
in order to "put it back", but I'm unsure if this is best practice or has implications for memory. I could also ostensibly implement Copy
on the metadata struct but it contains only fields with Vec<u32>
and u32
so this is not a great solution for my use case.
What is the most straightforward way to deal with this partial move?