Rust Structs and Enums
Structs and Enums in Rust:
Structs in Rust are used to create custom data types that group together related values.
A struct can be specified with individually named fields, a tuple-like fields, or no field (a unit-like struct).
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.