Trường riêng tư
Thuộc phần Lập trình hướng đối tượng trong hành trình Rust của Coddy. Bài học 10 trên 61.
Trong bài học trước, bạn đã đặt mọi thứ ở chế độ công khai: struct, các trường và các phương thức của nó. Nhưng tính đóng gói thực sự là kiểm soát cách dữ liệu có thể được truy cập. Trong Rust, bạn có thể đặt struct ở chế độ công khai trong khi vẫn giữ các trường ở chế độ riêng tư.
Hãy xem xét một Wallet không bao giờ được có số dư âm. Nếu trường này là công khai, bất kỳ ai cũng có thể đặt nó thành bất kỳ giá trị nào:
// wallet.rs
pub struct Wallet {
balance: f64, // Không có pub = riêng tư!
}
impl Wallet {
pub fn new(initial: f64) -> Wallet {
Wallet { balance: initial }
}
}
Lưu ý rằng Wallet là công khai, nhưng balance không có từ khóa pub. Điều này có nghĩa là code bên ngoài module có thể tạo Wallet bằng hàm khởi tạo, nhưng không thể đọc hoặc sửa đổi trực tiếp trường số dư:
// main.rs
mod wallet;
use wallet::Wallet;
fn main() {
let w = Wallet::new(100.0);
// println!("{}", w.balance); // Lỗi! Trường này là riêng tư
// w.balance = -50.0; // Lỗi! Không thể truy cập trường riêng tư
}
Đây là nền tảng của tính đóng gói: struct kiểm soát dữ liệu của chính nó. Code bên ngoài phải thông qua các phương thức bạn cung cấp, nhờ đó bạn có thể thêm bước xác thực, ghi nhật ký hoặc bất kỳ logic nào khác. Dữ liệu luôn được bảo vệ khỏi các trạng thái không hợp lệ.
Trong các bài học tiếp theo, bạn sẽ học cách cung cấp quyền truy cập có kiểm soát vào dữ liệu riêng tư này thông qua các phương thức (method) getter và setter.
Thử thách
DễHãy xây dựng một hệ thống cảm biến nhiệt độ để minh họa tính đóng gói bằng cách bảo vệ dữ liệu nhạy cảm bên trong một module.
Bạn sẽ tạo hai tệp để sắp xếp code:
sensor.rs: Định nghĩa một structTemperatureSensorvới hai trường:location(String) vàreading(f64). Struct này cần ở chế độ công khai để có thể dùng từ các tệp khác, nhưng hãy giữ cả hai trường ở chế độ riêng tư: code bên ngoài không thể truy cập hoặc sửa đổi trực tiếp dữ liệu của cảm biến. Thêm một hàm khởi tạonewcông khai, nhận tên địa điểm và số đo nhiệt độ ban đầu.main.rs: Khai báo module cảm biến và tạo mộtTemperatureSensorbằng hàm khởi tạo. Vì các trường ở chế độ riêng tư, bạn không thể in chúng trực tiếp, thay vào đó, hãy in thông báo xác nhận cho biết cảm biến đã được tạo thành công.
Thử thách này tập trung vào khái niệm cốt lõi về các trường riêng tư: bạn có thể truy cập struct, nhưng dữ liệu bên trong được bảo vệ. Code bên ngoài chỉ có thể tương tác với cảm biến thông qua các phương thức bạn cung cấp, trong trường hợp này chỉ là hàm khởi tạo.
Đầu ra của bạn phải theo đúng định dạng sau:
Sensor created for: {location}Để truy cập địa điểm và in ra, bạn cần để hàm new in thông báo này trước khi trả về cảm biến, vì bản thân trường này ở chế độ riêng tư.
Ví dụ: nếu bạn tạo cảm biến với địa điểm "Kitchen" và số đo 22.5, đầu ra sẽ là:
Sensor created for: KitchenBạn sẽ nhận hai đầu vào: tên địa điểm và số đo nhiệt độ ban đầu.
Tự làm thử
mod sensor;
use sensor::TemperatureSensor;
fn main() {
// Đọc đầu vào
let mut location = String::new();
std::io::stdin().read_line(&mut location).expect("Failed to read line");
let location = location.trim().to_string();
let mut reading_str = String::new();
std::io::stdin().read_line(&mut reading_str).expect("Failed to read line");
let reading: f64 = reading_str.trim().parse().expect("Failed to parse reading");
// TODO: Tạo TemperatureSensor bằng hàm khởi tạo
// Hàm new sẽ in thông báo xác nhận
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Phương thức và hành vi
Nhập môn khối triển khaiTham số selfPhương thức có thể thay đổiHàm liên kếtNhiều khối triển khaiNối chuỗi phương thứcÔn tập: thao tác với hình chữ nhật4Dự án: Thú cưng ảo
Định nghĩa thú cưngCho thú cưng ăn7Các trait tiêu chuẩn
Trait DebugTrait DisplayClone và CopyCác trait so sánh bằngÔn tập: Điểm có thể in ra2Tính đóng gói và module
Kiến thức cơ bản về moduleTừ khóa publicTrường riêng tưHàm lấy giá trịHàm thiết lập giá trịÔn tập: tủ khóa an toàn5Kiểu tổng quát
Cấu trúc tổng quátPhương thức tổng quátNhiều kiểu tổng quátHàm tổng quátÔn tập: điểm tọa độTự luyện tập: Trình biên dịch Rust online