Using the builder pattern
Sometimes you need something between the customization of the constructor and the implicitness of the default implementation. Enter the builder pattern, another technique frequently used by the Rust standard library, as it allows a caller to fluidly chain together configurations that they care about and lets them ignore details that they don't care about.
In Rust, the build concept is similar to functional programming; if you are familiar with C#, then you are definitely not a stranger to Linq.
Each function must return "itself" (&self), and when the construction is complete, it uses the build()
function to return a data.
Suppose you have a shopping list as follows:
struct shop_list {
Apple: i32,
pineapple: i32,
orange: i32,
}
We can use a builder to dynamically construct the list by defining a builder as follows:
struct shop_list_builder {
list: shop_list,
}
Implementing the builder:
impl shop_list_builder { fn new() -> Self { shop_list_builder { list: shop_list { Apple: 0, pineapple: 0, orange: 0, }, } } // build
fn apple(mut self, number: i32) -> Self { self.list.Apple = number; self } fn pineapple(mut self, number: i32) -> Self { self.list.pineapple = number; self } fn orange(mut self, number: i32) -> Self { self.list.orange = number; self } // build has complete fn build(mut self) -> shop_list { self.list }
}
Usage:
let instance = shop_list_builder::new() .apple(12) .pineapple(13) .orange(14) .build();
文章评论