Introduction to the

This article describes how to initialize responsible structures in Rust. The pub FN new() form and builder mode and Default mode are commonly used.

pub fn new()

The most common way to initialize a structure in Rust is to use pub fn new(). The general format is as follows:

pub fn new() - >Self {
  Self {
    // init}}Copy the code

This approach is very easy to use and concise. At the time, this was only suitable for short-answer constructs. For responsible constructs, there is a very long argument list, such as:

impl YakShaver {
  pub fn new(clipper_size: u32, gas_powered_clippers: bool, solar_powered_clippers: bool, color_to_dye_yak: &str) - >Self {
        // Body is irrelevant}}let yak_shaver = YakShaver::new(3.false.true."magenta");
Copy the code

Another problem is that when you need to add new YakShaver member variables, you need to change the new method, resulting in all the calls to the new method need to change, such as adding a clipper_color,

impl YakShaver {
    pub fn new(... sameasabove... , clipper_color: &str) - >Self {
        // Body is irrelevant}}let yak_shaver = YakShaver::new(3.false.true."magenta"."red");
Copy the code

Another problem with this is that all callers need to specify a color, even if 99%+ users only want to use a default black color.

Builder model

The Builder pattern is very neat because you don’t need to specify all of the member variables using the builder pattern, just the required ones.

pub struct YakShaverBuilder {
    clipper_size: u32,
    gas_powered_clippers: bool,
    solar_powered_clippers: bool,
    color_to_dye_yak: String,
    clipper_color: String,}impl YakShaverBuilder {
    pub fn new() - >Self {
        Self {
            clipper_size: 3,
            gas_powered_clippers: false,
            solar_powered_clippers: true,
            color_to_dye_yak: String::from("brown"),
            clipper_color: String::from("black"),}}pub fn clipper_size(mut self, v: u32) - >Self {
        self.clipper_size = v;
        self
    }

    pub fn gas_powered_clippers(mut self, v: bool) - >Self {
        self.gas_powered_clippers = v;
        self
    }

    pub fn solar_powered_clippers(mut self, v: bool) - >Self {
        self.solar_powered_clippers = v;
        self
    }

    pub fn color_to_dye_yak(mut self, v: String) - >Self {
        self.color_to_dye_yak = v;
        self
    }

    pub fn clipper_color(mut self, v: String) - >Self {
        self.clipper_color = v;
        self
    }

    pub fn build(self) -> YakShaver {
        YakShaver {
            clipper_size: self.clipper_size,
            gas_powered_clippers: self.gas_powered_clippers,
            solar_powered_clippers: self.solar_powered_clippers,
            color_to_dye_yak: self.color_to_dye_yak,
            clipper_color: self.clipper_color,
        }
    }
}

let yak_shaver = YakShaverBuilder::new()
    .clipper_size(4)
    .color_to_dye_yak(String::from("hot pink"))
    .clipper_color(String::from("red"))
    .build();
Copy the code

The Default mode

The Defaulttrait is provided in Rust, and implementing it initializes the struct with default values.

#[derive(Default, Debug)]
pub struct YakShaverInit {
    pub clipper_size: u32.pub gas_powered_clippers: bool.pub solar_powered_clippers: bool.pub color_to_dye_yak: String.pub clipper_color: String,}let yak_shaver = YakShaverInit {
    clipper_size: 4,
    color_to_dye_yak: String::from("hot pink"),
    clipper_color: String::from("red"),..Default: :default(),}let yak_shaver_default = Default: :default(a);Copy the code

The advantage of using the Default mode is that we only need to implement the Defaulttrait again. When initializing the struct, we only need to provide the parameters we need.