'How to prevent move in non-consuming builder pattern?
I am trying to create a struct with non-consuming builder pattern like this:
#[derive(Default)]
struct Person {
first_name: String,
last_name: String,
}
impl<'a> Person {
pub fn first_name(&'a mut self, name: &str) -> &'a mut Self {
self.first_name = name.to_owned();
self
}
pub fn last_name(&'a mut self, name: &str) -> &'a mut Self {
self.last_name = name.to_owned();
self
}
pub fn greet(&self) -> String {
format!("{:?} {:?}", self.first_name, self.last_name)
}
pub fn build(self) -> Self {
self
}
}
fn main() {
let person = Person::default()
.first_name("John")
.last_name("Doe")
.build();
let name = person.greet();
}
But when I use build() to get the value back, I get a move error like this:
error[E0507]: cannot move out of a mutable reference
--> builder/src/main.rs:27:18
|
27 | let person = Person::default()
| __________________^
28 | | .first_name("John")
29 | | .last_name("Doe")
30 | | .build();
| |________________^ move occurs because value has type `Person`, which does not implement the `Copy` trait
How can I use a non-consuming builder pattern while ensuring my code can work in multiple lines? Should I ditch the build() method?
Solution 1:[1]
I think you should use two struct, a PersonBuilder, and a Person. The PersonBuilder can collect the applicable info and its build method can check whether a complete Person can be built, and if so return a Person by moving its info into a new Person.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | hkBst |
