Structs

Rust by example - Structs


// We first define the struct's fields (which can be of any type).
// The `derive` attribute is not required - it just enables `println!` below.
#[derive(Debug)]
struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

fn main() {
    // We create an instance of the struct.
    // Note that there is no `new` or similar.
    let user1 = User {
        active: true,
        username: String::from("someusername123"),
        email: String::from("someone@example.com"),
        sign_in_count: 1,
    };
    println!("{:?}", user1);
}

Struct fields follow the general rule of everything being private by default unless annotated with pub⮳.


#[derive(Debug)]
struct User {
    active: bool,
    username: String,
    email: String,
}

// It is common to define a function (or an associated function, see below) that
// initializes the struct:
fn build_user(email: String, username: String) -> User {
    User {
        active: true,
        username, /* Field init shorthand, instead of writing `username:
                   * username` */
        email, // Same
    }
}

fn main() {
    // We create an instance of the struct:
    let user1: User = build_user("user@example.com".into(), "user".to_string());

    // Then update the struct.
    // .. is used to fill in the rest
    let user2 = User {
        email: String::from("another@example.com"),
        ..user1 /* The remaining fields not explicitly set will have the
                 * same value as the fields in the given instance. */
    };
    println!("{:?}", user2);
}

// A tuple struct
// Note the ( ) and the lack of field names.
#[derive(Debug)]
struct Color(i32, i32, i32);

// A unit-like struct
#[derive(Debug)]
struct AlwaysEqual; // Note that there are no fields

fn main() {
    let black = Color(0, 0, 0);
    println!("{black:?}");
    let s = AlwaysEqual;
    println!("{s:?}");
}
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // implementation block (multiple allowed for a given struct)
    // Method
    fn area(&self) -> u32 {
        // short for self: &Self, an alias for the type that the impl block is
        // for
        self.width * self.height
    }

    // Associated Functions - NO self, &self, or &mut self
    // often use for constructors: SomeType::new(...)
    fn square(size: u32) -> Self {
        Self {
            width: size,
            height: size,
        }
    }
}

fn main() {
    let sq = Rectangle::square(5);
    println!("Area: {}", sq.area());
}