Structs in Rust

Structs in Rust

Introduction

Struct or Structure is a Data Structure in Rust, where you can group multiple data types. This is very similar to tuples, but unlike in Structs all data types are named. They're also called as key-value pairs, the name being the key and the value being the value stored.

Examples

Below is how we declare a struct.

struct Player {
    player_name: String,
    pos_x: i32,
    pos_y: i32,
    hp: u16,
    is_alive: bool,
}

And this is how we instantiate a struct.

fn main() {
    let player1 = Player {
        player_name: String::from("John Cena"),
        pos_x: 0,
        pos_y: 0,
        hp: 100,
        is_alive: true,
    };
}

To get a field, the player_name or hp for example, you can use dot . operator

fn main() {
    let player1 = Player {
        player_name: String::from("John Cena"),
        pos_x: 0,
        pos_y: 0,
        hp: 100,
        is_alive: true,
    };
    println!("Name: {}", player1.player_name);
    println!("HP: {}", player1.hp);
}

We can also change the values if we instatiate a mutable player1

fn main() {
    let mut player1 = Player {
        player_name: String::from("John Cena"),
        pos_x: 0,
        pos_y: 0,
        hp: 100,
        is_alive: true,
    };
    player1.player_name = String::from("Prince Vegeta");
    player1.hp = 50;
    println!("Name: {}", player1.player_name);
    println!("HP: {}", player1.hp);
}

NOTE: The whole struct will be mutable, it is not possible to create a struct with both mutable and immutable fields

We can also define another player2 only changing the name using the .. operator. The other values will be same as player1

fn main() {
    let mut player1 = Player {
        player_name: String::from("John Cena"),
        pos_x: 0,
        pos_y: 0,
        hp: 100,
        is_alive: true,
    };

    let player2 = Player {
        player_name: String::from("Prince Vegeta"),
        ..player1
    };
    println!("Name: {}", player2.player_name);
    println!("HP: {}", player2.hp);
}

Right now everything is happening inside the main function. Lastly we'll see how we can use a function instead to populate the values.

fn main() {
    let player1 = populate_struct(String::from("Prince Vegeta"), 50);
    println!("{:#?}", player1);
}

fn populate_struct(player_name: String, hp: u16) -> Player {
    Player {
        player_name: player_name,
        pos_x: 0,
        pos_y: 0,
        hp: hp,
        is_alive: true
    }
}

This is a better approach to keep the main function clean.

We can also use the shorthand.

fn populate_struct(player_name: String, hp: u16) -> Player {
    Player {
        player_name,
        pos_x: 0,
        pos_y: 0,
        hp,
        is_alive: true
    }
}

Conclusion

That's all about structs in brief. There are also few unconventional kinds of structs like tuple structs and unit structs. We'll discuss about them gradually!