Search code examples
ruststructinitializationlazy-initialization

Best way to lazy initialize struct members?


I have this struct:

pub struct NonSteamGame {
    app_id:String ,
    app_name:String,
    start_dir:String,
    icon:String,
    shortcut_path:String,
    launch_options:String,
    is_hidden:bool,
    allow_desktop_config:bool,
    allow_overlay:bool,
    open_vr:bool,
    devkit:bool,
    devkit_game_id:String,
    devkit_override_app_id:String,
    last_play_time:String,
    flatpack_app_id:String
}

All these field values are read from a stream and set as they are read.

Is there any way to be able to create an instance without manually initializing all the struct members to assign them as I get their values from the stream? An example (pseudo code):

let nsg = NonSteamGame {} //Do not initialize all values manually here

... get property_name and value from stream...

match property_name {
    "appid" => nsg.app_id = String::new(value)
    "AppName" => nsg.app_name = String::new(value)
    "StartDir" => ...
    "icon" => ...
}

I know I could use #[derive(Default)] for scalar types but it seems it doesn't work for String type.


Solution

  • Probably the best option for this case would be to derive the Default trait.

    #[derive(Default)]
    pub struct NonSteamGame {
        app_id:String ,
        app_name:String,
    ...
    

    Then, instead of ::new(), instantiate with NonSteamGame::default(). You can even make the new facade if you need to keep the backward compatibility:

        pub fn new() -> Self {
            Self::default()
        }