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_useris 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 };
}..user1is a shorthand to copy the values ofuser1touser2
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 theDebugtrait{:?}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 Rectangleis used to define methods for theRectanglestruct
#[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);
}