singularity

Defining and Instantiating Structs

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}
fn main() {
    let mut user1 = User {
        active: true,
        username: String::from("someusername123"),
        email: String::from("someone@example.com"),
        sign_in_count: 1,
    };
    
    user1.email = String::from("anotheremail@example.com");

}

Using the Field Init Shorthand

fn build_user(email: String, username: String) -> User {
    User {
        active: true,
        username,
        email,
        sign_in_count: 1,
    }
}

Creating Instances from Other Instances with Struct Update Syntax

    let user2 = User {
        email: String::from("another@example.com"),
        ..user1 //must come last
    };

    //will not work 
    //println!("{}", user1.username); 

    let user3 = User {
        active: user2.active,
        sign_in_count: user2.sign_in_count,
        username: String::from("someusername123"),
        email: String::from("someone@example.com"),
    };

    println!("{}", user3.username); 

Using Tuple Structs Without Named Fields to Create Different Types

struct Color(i32, i32, i32);
struct Point(i32, i32, f32);

fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0.1);
}

Unit-Like Structs Without Any Fields

struct AlwaysEqual;

fn main() {
    let subject = AlwaysEqual;
}

An Example Program Using Structs

Adding Useful Functionality with Derived Traits

struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {}", rect1);
}
error[E0277]: `Rectangle` doesn't implement `std::fmt::Display`
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {rect1:?}");
}

Method Syntax

Defining Methods

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
    );
}

Methods with More Parameters

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }

    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}

Associated Functions

impl Rectangle {
    fn square(size: u32) -> Self {
        Self {
            width: size,
            height: size,
        }
    }
}

Multiple impl Blocks

struct self/cross-referencing

// cross referencing
impl Printer {
    // A public method in Printer struct that uses an instance of Calculator
    pub fn print_sum(&self, calculator: &Calculator, x: i32, y: i32) {
        let sum = calculator.add(x, y); // Calling Calculator's method
        println!("The sum of {} and {} is: {}", x, y, sum);
    }
}