← Rust EnglishChapter 06 of 13

Structs

## Learning Objectives - Define and instantiate structs - Use method syntax with impl - Create associated functions - Understand tuple structs - Master struct updating ## Defining Structs ### Classic Struct ```rust struct Rectangle { width: u32, height: u32, } fn main() { let rect = Rectangle { width: 30, height: 50, }; println!("{} x {}", rect.width, rect.height); } ``` ### Tuple Struct ```rust struct Point(i32, i32); struct Color(u8, u8, u8); fn main() { let point = Point(10, 20); let color = Color(255, 0, 0); println!("{} {}", point.0, point.1); println!("R {} G {} B {}", color.0, color.1, color.2); } ``` ### Unit-Like Struct ```rust struct AlwaysEqual; fn main() { let _subject = AlwaysEqual; } ``` ## Instantiating Structs ### Create Instance ```rust struct User { username: String, email: String, sign_in_count: u64, active: bool, } fn main() { let user1 = User { email: String::from("alice@example.com"), username: String::from("alice123"), active: true, sign_in_count: 1, }; } ``` ### Field Init Shorthand ```rust fn build_user(email: String, username: String) -> User { User { email, // Same as email: email username, // Same as username: username active: true, sign_in_count: 1, } } ``` ## Mutating Struct Fields ```rust struct Rectangle { width: u32, height: u32, } fn main() { let mut rect = Rectangle { width: 30, height: 50, }; rect.width = 40; println!("{} x {}", rect.width, rect.height); } ``` ## Method Syntax ### impl Block ```rust impl Rectangle { fn area(&self) -> u32 { self.width * self.height } } fn main() { let rect = Rectangle { width: 30, height: 50 }; println!("Area: {}", rect.area()); } ``` ### Methods with Parameters ```rust 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 set_width(&mut self, width: u32) { self.width = width; } } ``` ### Associated Functions Functions that don't take `self` as parameter: ```rust impl Rectangle { fn new(width: u32, height: u32) -> Rectangle { Rectangle { width, height } } fn square(size: u32) -> Rectangle { Rectangle { width: size, height: size } } } fn main() { let rect = Rectangle::new(30, 50); let sq = Rectangle::square(20); } ``` ### Multiple impl Blocks ```rust impl Rectangle { fn area(&self) -> u32 { self.width * self.height } } impl Rectangle { fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.height > other.height } } ``` ## Struct Update Syntax ### Copy All Fields ```rust struct Point { x: i32, y: i32, z: i32, } fn main() { let p1 = Point { x: 1, y: 2, z: 3 }; let p2 = Point { x: 10, ..p1 // Copy remaining fields from p1 }; println!("{} {} {}", p2.x, p2.y, p2.z); // 10 2 3 } ``` ### With Tuple Structs ```rust struct Point(i32, i32, i32); fn main() { let p1 = Point(1, 2, 3); let p2 = Point(10, ..p1); println!("{} {} {}", p2.0, p2.1, p2.2); // 10 2 3 } ``` ## Ownership in Structs ### Owned Values ```rust struct User { username: String, email: String, } fn main() { let user = User { email: String::from("alice@example.com"), username: String::from("alice123"), }; // user.email and user.username own their data } ``` ### Reference Values ```rust struct User { username: &str, // Lifetimes needed! email: &str, } // Better approach: use owned String struct User { username: String, email: String, } ``` ## Example: Rectangle with Methods ```rust #[derive(Debug)] struct Rectangle { width: u32, height: u32, } impl Rectangle { fn new(width: u32, height: u32) -> Rectangle { Rectangle { width, height } } fn square(size: u32) -> Rectangle { Rectangle { width: size, height: size } } fn area(&self) -> u32 { self.width * self.height } fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.height > other.height } fn width(&self) -> u32 { self.width } fn height(&self) -> u32 { self.height } } fn main() { let rect = Rectangle::new(30, 50); let sq = Rectangle::square(20); println!("{:?}", rect); println!("Area: {}", rect.area()); println!("Can hold square? {}", rect.can_hold(&sq)); } ``` ## Debug Trait ```rust #[derive(Debug)] struct Rectangle { width: u32, height: u32, } fn main() { let rect = Rectangle { width: 30, height: 50 }; println!("{:?}", rect); // Debug format println!("{:#?}", rect); // Pretty debug } ``` ## Summary - Structs group related data - Tuple structs name tuple collections - Unit-like structs for marker types - Methods defined in `impl` blocks - `&self` borrows the instance - Associated functions don't take `self` (constructors) - Struct update syntax `..` copies remaining fields - Use `#[derive(Debug)]` for debug output

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →