Objective
Struct and Custom Data Types in Rust
By the end of this lesson, you will understand how to define and use structs in Rust to create custom data types. You will learn the syntax for defining structs, how to create instances, and explore basic, complex, and advanced examples of their usage.
1. What is a Struct?
In Rust, a struct (short for structure) is a custom data type that allows you to group related data together. Structs are similar to classes in other languages but do not include methods by default. They are ideal for modeling complex data structures.
Basic Syntax of Structs:
struct StructName {
field1: FieldType1,
field2: FieldType2,
// Add more fields as needed
}
2. Defining a Basic Struct
Let’s start with a simple example: defining a Book
struct to hold information about a book.
Example: Basic Struct
struct Book {
title: String,
author: String,
pages: u32,
}
fn main() {
let book1 = Book {
title: String::from("The Rust Programming Language"),
author: String::from("Steve Klabnik and Carol Nichols"),
pages: 552,
};
println!("Title: {}, Author: {}, Pages: {}", book1.title, book1.author, book1.pages);
}
In this example, we define a Book
struct with three fields: title
, author
, and pages
. We then create an instance of the struct and print its details.
3. Complex Structs: Structs with Methods
You can define methods for structs using impl
, allowing you to encapsulate functionality along with your data.
Example: Struct with Methods
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// Method to calculate the area of the rectangle
fn area(&self) -> u32 {
self.width * self.height
}
// Method to determine if it is a square
fn is_square(&self) -> bool {
self.width == self.height
}
}
fn main() {
let rect1 = Rectangle {
width: 10,
height: 20,
};
println!("Area: {}", rect1.area()); // Outputs: Area: 200
println!("Is square: {}", rect1.is_square()); // Outputs: Is square: false
}
In this example, the Rectangle
struct has methods to calculate the area and check if it is a square. This encapsulates the behavior related to the data.
4. Advanced Structs: Tuple Structs
Rust also supports tuple structs, which are like regular structs but do not require field names. Instead, you access the data by its index.
Example: Tuple Structs
struct Color(u8, u8, u8); // Tuple struct to represent RGB color
fn main() {
let black = Color(0, 0, 0);
let white = Color(255, 255, 255);
println!("Black: ({}, {}, {})", black.0, black.1, black.2); // Outputs: Black: (0, 0, 0)
println!("White: ({}, {}, {})", white.0, white.1, white.2); // Outputs: White: (255, 255, 255)
}
In this example, the Color
tuple struct is used to represent an RGB color. You can access the color components using their index.
5. Advanced Example: Structs with Associated Functions
You can also define associated functions for a struct, which are similar to static methods in other languages. These functions can create instances of the struct.
Example: Struct with Associated Functions
struct Circle {
radius: f64,
}
impl Circle {
// Associated function to create a new Circle
fn new(radius: f64) -> Circle {
Circle { radius }
}
// Method to calculate the circumference
fn circumference(&self) -> f64 {
2.0 * std::f64::consts::PI * self.radius
}
}
fn main() {
let circle1 = Circle::new(5.0); // Create a new Circle using the associated function
println!("Circumference: {}", circle1.circumference()); // Outputs the circumference
}
In this example, the Circle
struct has an associated function new
that initializes a new instance and a method to calculate the circumference.
6. Conclusion
In this lesson, you learned how to define and use structs in Rust to create custom data types. You explored basic struct definitions, complex structs with methods, and advanced usage such as tuple structs and associated functions. Structs are a powerful feature in Rust, enabling you to model real-world data effectively.