30 Ngày học Rust - Day 6: Đắp nặn dự án với Structs và Methods
Day 6: Biến đổi các nhóm biến rời rạc thành các Cấu trúc dữ liệu có ý nghĩa (Structs) và gán hành vi cho chúng bằng Methods trong Rust.

Lắp ráp những khối Lego đầu tiên
Nếu chỉ có chuỗi String, số nguyên Integer và Boolean, bạn không thể mô tả được một “Người Dùng”. Một người dùng làm bằng email (String), tuổi (u8) và trạng thái online (bool). Không thể mỗi lần viết hàm lại truyền tận 3 biến rời rạc vào được.
Giải pháp ở đây là gom chúng lại vào một chiếc hộp dán nhãn User. Trong Rust, vật chứa đó gọi là Nhóm cấu trúc Structs. Nếu bạn đã dùng qua JavaScript, Struct giống hệt như một Object cấu tạo bằng class.
1. Định nghĩa và Khởi tạo Struct
Giống như việc tạo bản vẽ trước khi xây nhà, bạn cần quy định kiểu dáng Struct:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}Để đúc ra một thực thể sống (Instance) từ bản thiết kế trên, bạn gắn value cho chúng:
fn main() {
// Lưu ý: Nếu muốn đổi email sau này, phải khai báo "mut user1"
let mut user1 = User {
email: String::from("[email protected]"),
username: String::from("thanhnam"),
active: true,
sign_in_count: 1,
};
user1.email = String::from("[email protected]");
}Một cú pháp cực xịn sò của Rust: Nếu bạn muốn tạo user2 giống hệt user1 nhưng chỉ khác tên, bạn có thể xài cú pháp Struct Update Syntax:
let user2 = User {
username: String::from("nam_pro"),
..user1 // Ba dấu chấm ... sao? Không, trong Rust là 2 dấu chấm (..) hứng toàn bộ!
};Cú pháp cướp giật này làm user1 mất sạch quyền Ownership các biến String bên trong. Gọi lại user1.email sẽ crash app.
2. Tuple Structs - Chút bụi của toán học
Nhiều lúc bạn không cần đặt tên cho từng trường thông tin. Cứ vứt thẳng giá trị vào cho lẹ. Trường hợp kinh điển nhất là tọa độ Màu sắc hoặc 3D:
struct Color(i32, i32, i32);
struct Point(i32, i32, i32); // Hai cái này khác hệ quy chiếu dù giống y hệt kiểu ruột
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);3. Khai mở sức mạnh với Methods (Phương thức)
Cấu trúc tĩnh thì chỉ như bức tượng vô tri. Để tượng có thể di chuyển, bạn cần gắn “Hành vi” vào nó. Hành vi nằm bên trong khối impl (Implementation - Thực thi).
struct HinhChuNhat { width: u32, height: u32 }
impl HinhChuNhat {
// &self là ám chỉ nó mượn bộ nhớ của chính "bản thân nó" để chạy
fn dien_tich(&self) -> u32 {
self.width * self.height
}
// Hàm KHÔNG cần &self gọi là HÀM LIÊN KẾT (Tương đương Static Method/Constructor)
fn hinh_vuong(size: u32) -> HinhChuNhat {
HinhChuNhat { width: size, height: size }
}
}
fn main() {
let rect1 = HinhChuNhat { width: 30, height: 50 };
println!("Diện tích: {}", rect1.dien_tich());
// Gọi hàm Static bằng dấi "::"
let sq = HinhChuNhat::hinh_vuong(10);
}Câu hỏi thường gặp (FAQ)
Rust có tính Nạp chồng phương thức (Method Overloading) không?
Giống như nhiều tính năng nhập nhằng của C++/Java, Rust nói “KHÔNG” với Method Overloading (Định nghĩa 2 hàm trùng tên nhưng khác tham số). Mỗi hàm đều phải có một cái tên đặc trưng rõ ràng để Trình biên dịch hiểu trong một phần nghìn giây. Ví dụ: Viết hàm parse_int() và parse_float() phân định rạch ròi.
Có cách nào in nhanh cấu trúc Struct ra màn hình để debug không?
Mặc định bạn không thể dùng println!("{}", user1) (bị báo lỗi chưa implement Display trait). Cách hack nhanh nhất cho debug là thêm dòng #[derive(Debug)] gián tiếp ngay trên chữ struct User {. Sau đó khi in bạn dùng cú pháp {:?} hoặc {:#?} (in dọc thụt lề đẹp mắt): println!("{:#?}", user1);
Sẵn sàng cho Ngày 7? Bạn nghĩ Struct đã là điểm sáng nhất của Khung phân nhóm dữ liệu? Chờ tới bài ngày mai nhé. Chúng ta sẽ nâng cấp khái niệm Tùy biến đến mức tối đa với một công cụ mà hiếm ngôn ngữ nào bì được: [Day 7: Enums & Pattern Matching].
Chuỗi bài viết
30 Ngày Trở Thành Rustacean Tinh Hoa
Phần 6 / 30
- Phần 1 30 Ngày học Rust - Day 1: Lời chào thế giới và Vũ khí Cargo
- Phần 2 30 Ngày học Rust - Day 2: Biến, Bất biến (Mutability) và Shadowing
- Phần 3 30 Ngày học Rust - Day 3: Luồng điều khiển (Control Flow) và sức mạnh của Match
- Phần 4 30 Ngày học Rust - Day 4: Ownership - Khái niệm định hình cỗ thần khí Rust
- Phần 5 30 Ngày học Rust - Day 5: Khóa học nhặt đồ chung với References & Borrowing
- Phần 6 30 Ngày học Rust - Day 6: Đắp nặn dự án với Structs và Methods
- Phần 7 30 Ngày học Rust - Day 7: Quyền năng vô song của Enums và Pattern Matching
- Phần 8 30 Ngày học Rust - Day 8: Quản lý dự án với Packages, Crates và Modules
- Phần 9 30 Ngày học Rust - Day 9: Các bộ sưu tập chung (Vectors, Strings, Hash Maps)
- Phần 10 30 Ngày học Rust - Day 10: Trị dứt điểm Ác mộng Lỗi (Error Handling)
- Phần 11 30 Ngày học Rust - Day 11: Generics - Ma thuật Đa hình kiểu dữ liệu
- Phần 12 30 Ngày học Rust - Day 12: Traits - Kẻ ban phát quyền năng và Lập pháp Hành vi
- Phần 13 30 Ngày học Rust - Day 13: Vượt qua Boss cuối 'Lifetimes' - Sinh Mệnh Biến
- Phần 14 30 Ngày học Rust - Day 14: Tận diệt Bug từ trứng nước bằng Automated Tests
- Phần 15 30 Ngày học Rust - Day 15: Thực chiến Build Command Line App (CLI) đầu đời
- Phần 16 30 Ngày học Rust - Day 16: Functional Magic chốn trần gian (Closures & Iterators)
- Phần 17 30 Ngày học Rust - Day 17: Quyền năng của Smart Pointers
- Phần 18 30 Ngày học Rust - Day 18: Chinh phục Da luồng (Concurrency) - Cú đâm quyết định của Rust
- Phần 19 30 Ngày học Rust - Day 19: Tranh cãi Lập trình hướng đối tượng (OOP) trong Rust
- Phần 20 30 Ngày học Rust - Day 20: Mổ xẻ nghệ thuật Advanced Pattern Matching
- Phần 21 30 Ngày học Rust - Day 21: Sức mạnh tối thượng của Advanced Traits
- Phần 22 30 Ngày học Rust - Day 22: Về Phe Bóng Tối với Unsafe Rust
- Phần 23 30 Ngày học Rust - Day 23: Quyền năng của Đấng Tạo Hóa (Declarative Macros)
- Phần 24 30 Ngày học Rust - Day 24: Siêu Năng Lực Procedural Macros (Macro Thủ Tục)
- Phần 25 30 Ngày học Rust - Day 25: Xây dựng TCP Web Server Đa Luồng (Phần 1: Lõi Socket)
- Phần 26 30 Ngày học Rust - Day 26: Xây dựng TCP Web Server Đa Luồng (Phần 2: Bắn trả File HTML)
- Phần 27 30 Ngày học Rust - Day 27: Xây dựng TCP Web Server Đa Luồng (Phần 3: The Thread Pool)
- Phần 28 30 Ngày học Rust - Day 28: Xây dựng TCP Web Server Đa Luồng (Phần 4: Graceful Shutdown)
- Phần 29 30 Ngày học Rust - Day 29: Lên đỉnh Web Server Thực Chiến với Axum và Tokio
- Phần 30 30 Ngày học Rust - Day 30: Vượt Vọng Vàng - Đúc Kết Hành Trình Rustacean Tinh Hoa