Struct trong Rust
Định nghĩa kiểu dữ liệu tùy chỉnh trong Rust với struct thông thường, tuple struct, unit struct và cài đặt phương thức trong khối impl.
Bài thứ bảy trong loạt Rust cơ bản. Struct giúp bạn nhóm các giá trị liên quan lại thành một kiểu dữ liệu tùy chỉnh để mô hình hóa các khái niệm có cấu trúc trong chương trình.
Khai báo và khởi tạo struct#
Một struct thông thường chứa các trường có tên:
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
fn main() {
let user1 = User {
active: true,
username: String::from("alice"),
email: String::from("alice@example.com"),
sign_in_count: 1,
};
println!("Tên người dùng: {}", user1.username);
}rustNếu tên trường trùng với tên biến trong phạm vi, bạn có thể dùng cú pháp viết tắt:
fn build_user(email: String, username: String) -> User {
User {
active: true,
username,
email,
sign_in_count: 1,
}
}rustCú pháp cập nhật struct#
Tạo một instance mới dựa trên các giá trị từ instance cũ với cú pháp ..:
let user2 = User {
email: String::from("bob@example.com"),
..user1
};rustLưu ý rằng các trường có ngữ nghĩa move (như username trong user1) sẽ bị di chuyển sang user2.
Tuple struct và unit-like struct#
Tuple struct có các trường không tên, truy cập qua chỉ số vị trí:
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);rustUnit-like struct không chứa trường nào, hữu ích khi cài đặt trait mà không cần lưu trữ trạng thái:
struct AlwaysEqual;
let subject = AlwaysEqual;rustPhương thức và khối impl#
Định nghĩa các phương thức cho struct bên trong khối impl. Tham số đầu tiên thường là &self (để mượn), &mut self (để chỉnh sửa), hoặc self (để nhận quyền sở hữu):
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
}
// Hàm liên kết (associated function - constructor)
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!("Diện tích: {}", rect1.area());
let sq = Rectangle::square(20);
println!("Có thể chứa hình vuông không? {}", rect1.can_hold(&sq));
}rustKết luận#
Struct cho phép bạn tạo ra các kiểu dữ liệu chuyên biệt có tên trường hoặc vị trí tuple, kết hợp với khối impl để đóng gói hành vi cùng dữ liệu. Bài tiếp theo trong loạt: enum và pattern matching.