Rust Structs and Enums

Declaring of Structs:

Named Fields Struct:

                    
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn main() {
    let user1 = User {
        username: String::from("user1"),
        email: String::from("user1@example.com"),
        sign_in_count: 1,
        active: true,
    };

    println!("Username: {}", user1.username);
}
                    
                  

Tuple Struct:

                    
struct Color(i32, i32, i32);

fn main() {
    let black = Color(0, 0, 0);
    println!("Color: ({}, {}, {})", black.0, black.1, black.2);
}
                    
                  

Unit-like Struct:

                    
struct AlwaysEqual;

fn main() {
    let subject = AlwaysEqual;
}
                    
                  

Enums and Pattern Matching:

Enums:

Enums in Rust are used to define a type that can have multiple variants.

Any type of variance can be associated with varying types and levels of data.

Example:

                    
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let msg = Message::Move { x: 10, y: 20 };
    match msg {
        Message::Quit => println!("Quit"),
        Message::Move { x, y } => println!("Move to ({}, {})", x, y),
        Message::Write(text) => println!("Write: {}", text),
        Message::ChangeColor(r, g, b) => println!("Change color to RGB({}, {}, {})", r, g, b),
    }
}
                    
                  

Pattern Matching:

Pattern matching with match allows you to compare a value against a series of patterns and execute code based on which pattern matches.

Example:

                    
fn main() {
    let number = 7;

    match number {
        1 => println!("One"),
        2 => println!("Two"),
        3 => println!("Three"),
        4..=9 => println!("Between four and nine"),
        _ => println!("Something else"),
    }
}
                    
                  

Implementing Methods for Structs

You can implement methods for structs using impl blocks.

Methods can be either static functions (usually used as constructors) or instance methods that take self (often used as a first argument).

Example:

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

impl Rectangle {
    // Associated function
    fn new(width: u32, height: u32) -> Rectangle {
        Rectangle { width, height }
    }

    // Instance method
    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::new(30, 50);
    let rect2 = Rectangle::new(10, 40);

    println!("The area of rect1 is {} square pixels.", rect1.area());
    println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
}
                    
                  

Summary:

  • Structs: Used to group related data together. Can be named, tuple-like, or unit-like.
  • Enums: Introduce a type with various, possible diverse, derivatives. Helpful for dealing with data that might be any one of several types.
  • Pattern Matching: A powerful feature for handling different enum variants or other conditions.
  • Methods: Implement methods on structs using impl blocks to provide functionality and behavior.

Therefore, they provide a rich abstraction and make it possible to build data structures for complicated and give it a convenient implementation of the Rust code.