🚀
4. Structs

Structs

  • Allows grouping related data of different types
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}
 
fn main() {
    let user1 = User {
        username: String::from("user1"),
        email: String::from("user@email.com"),
        sign_in_count: 1,
        active: true,
    };
 
    let name = user1.username;
 
    println!("Username: {}", name);
}
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}
 
fn main() {
    let mut user1 = User {
        username: String::from("user1"),
        email: String::from("user@email.com"),
        sign_in_count: 1,
        active: true,
    };
 
    let name = user1.username;
 
    println!("Username: {}", name);
 
    user1.username = String::from("user2");
}

Contructors

  • init_user is a functional contructor that create instances of structs
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}
 
fn init_user(username: String, email: String) -> User {
    User {
        username,
        email,
        sign_in_count: 1,
        active: true,
    }
}
 
fn main() {
    let user1 = init_user(String::from("user1"), String::from("user@email.com"));
 
    let user2 = User { ..user1 };
 
}
  • ..user1 is a shorthand to copy the values of user1 to user2

Tuple Structs

  • Similar to tuples but with named fields
fn main() {
    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);
}

Example

fn main() {
    let width1 = 30;
    let height1 = 50;
 
    println!(
        "The area of the rectangle is {} square pixels.",
        area(width1, height1)
    );
}
 
fn area(width: u32, height: u32) -> u32 {
    width * height
}
 
  • The above code is not very readable, we can use tuple structs to improve it
fn main() {
    let rect = (30, 50);
 
    println!("The area of the rectangle is {} square pixels.", area(rect));
}
 
fn area(dimensions: (u32, u32)) -> u32 {
    dimensions.0 * dimensions.1
}
  • The above code is still not very readable, we can use structs to improve it
fn main() {
    let rect = Rectangle {
        width: 30,
        height: 50,
    };
 
    println!(
        "The area of the rectangle is {} square pixels.",
        area(&rect)
    );
}
 
fn area(rect: &Rectangle) -> u32 {
    rect.width * rect.height
}

Printing Structs

  • Use {:?} to print the struct
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}
 
fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
 
    println!("rect1 is {:?}", rect1);
    // Output: rect1 is Rectangle { width: 30, height: 50 }
 
    println!("rect1 is {:#?}", rect1);
    // Output:
    // rect1 is Rectangle {
    //     width: 30,
    //     height: 50
    // }
}
  • #[derive(Debug)] is a trait that allows the compiler to provide a default implementation of the Debug trait
  • {:?} is used to print the struct in a single line
  • {:#?} is used to print the struct in multiple lines

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()
    );
 
    // Output: The area of the rectangle is 1500 square pixels.
}
  • impl Rectangle is used to define methods for the Rectangle struct
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}
 
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
    }
}
 
fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
 
    let rect2 = Rectangle {
        width: 10,
        height: 40,
    };
 
    print!("rect1 can hold rect2: {}", rect1.can_hold(&rect2));
 
    // Output: rect1 can hold rect2: true
}

Associated Functions

  • Functions that are associated with the struct
struct Rectangle {
    width: u32,
    height: u32,
}
 
impl Rectangle {
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}
 
fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
 
    let rect2: Rectangle = Rectangle::square(30);
}

© 2024 Driptanil Datta.All rights reserved

Made with Love ❤️

Last updated on Mon Oct 20 2025