Table of contents
Open Table of contents
1. 3 Quy tắc vàng của Ownership
Bạn cần thuộc lòng 3 quy tắc sau để “sống sót” trong thế giới của Rust:
- Mỗi giá trị trong Rust đều có một biến là chủ sở hữu (owner) của nó.
- Tại một thời điểm, chỉ có duy nhất một chủ sở hữu.
- Khi chủ sở hữu ra khỏi phạm vi (scope), giá trị sẽ bị xóa khỏi bộ nhớ ngay lập tức.
2. Di chuyển dữ liệu (Move)
Khi bạn gán một biến phức tạp (như String) cho một biến khác, Rust sẽ di chuyển quyền sở hữu thay vì sao chép.
let s1 = String::from("Hello");
let s2 = s1; // s1 bị "Move" quyền sở hữu sang s2
// println!("{}", s1); // Lỗi! s1 không còn giá trị nữa.
println!("{}", s2); // Hợp lệ.
Tại sao lại Move?
Để đảm bảo chỉ có 1 biến chịu trách nhiệm dọn dẹp vùng nhớ đó, tránh lỗi “double free” (xóa bộ nhớ 2 lần).
3. Sao chép dữ liệu (Clone)
Nếu bạn thực sự muốn cả hai biến đều có một bản sao riêng biệt, hãy dùng .clone(). Tuy nhiên, việc này sẽ tốn tài nguyên hơn (copy bộ nhớ).
let s1 = String::from("Hello");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2); // Cả hai đều dùng được!
4. Mượn (Borrowing) và Tham chiếu (References)
Thay vì lấy luôn quyền sở hữu, bạn có thể “mượn” nó bằng cách sử dụng dấu &.
let s1 = String::from("Hello");
let len = &s1; // b chỉ đang "mượn" s1 để xem
println!("s1 vẫn còn: {}", s1);
Hai loại mượn:
- Mượn để đọc (
&T): Bạn có thể có vô số người mượn để đọc cùng lúc. - Mượn để sửa (
&mut T): Bạn chỉ có thể có duy nhất 1 người mượn để sửa tại một thời điểm.
let mut s = String::from("Hello");
let r1 = &mut s; // Hợp lệ
r1.push_str(" World");
Lời kết Bài 10
Ownership và Borrowing có thể khiến bạn hơi bối rối lúc đầu (đặc biệt là khi Compiler báo lỗi liên tục), nhưng hãy kiên nhẫn. Một khi đã làm chủ được chúng, bạn sẽ viết được những chương trình “bất tử”, không bao giờ gặp lỗi bộ nhớ hay crash bất ngờ.
Hẹn gặp lại các bạn ở bài sau với chủ đề Hàm (Functions)!