
Ownership là gì?
Rust là ngôn ngữ lập trình đầu tiên đưa ownership vào type system để quản lý bộ nhớ. Mỗi giá trị trong Rust có một owner duy nhất; khi owner ra khỏi phạm vi, giá trị bị dropped và bộ nhớ được giải phóng tự động — không cần garbage collector, không cần gọi free thủ công.
Ownership giải quyết ba lỗi bộ nhớ phổ biến: use-after-free, double free, data race. Nếu vi phạm bất kỳ quy tắc nào, chương trình sẽ không compile được — lỗi bộ nhớ được phát hiện lúc biên dịch chứ không lúc chạy.

Ba quy tắc ownership (nhớ kỹ)
Theo tài liệu chính thức của Rust, ownership hoạt động dựa trên ba quy tắc cơ bản:
- Mỗi giá trị có một owner duy nhất.
- Tại một thời điểm chỉ có một owner cho mỗi giá trị.
- Khi owner ra khỏi scope, giá trị bị dropped.
Ba quy tắc này đảm bảo compile-time safety mà không cần GC runtime.
Move semantics
Kiểu nằm trên stack (i32, let x = 5; let y = x;) → gán tạo copy. Kiểu dùng heap (String): let s1 = String::from("hello"); let s2 = s1; → move. s1 không còn hợp lệ sau lệnh gán.
Lý do: nếu copy con trỏ mà vẫn để cả hai s1/s2 dùng chung thì sẽ xảy ra double free (giải phóng bộ nhớ 2 lần). Rust ngăn chuyện này ngay lúc biên dịch. Khi cố dùng s1 sau move, bạn sẽ thấy lỗi:
error[E0382]: borrow of moved value: `s1`
Muốn copy thật sự (heap) → dùng .clone() (trait Clone).

Borrowing và borrow checker
Borrow checker là bộ phận trình biên dịch, kiểm tra statically rằng các tham chiếu luôn trỏ tới object hợp lệ. Trong khi còn reference tồn tại, object không thể bị destroy.
Thay vì lấy ownership, bạn có thể mượn bằng cách tạo reference &T:
fn calculate_length(s: &String) -> usize { s.len() }
Vì reference không sở hữu, giá trị trỏ tới sẽ không bị dropped khi reference hết vòng đời.
Immutable vs Mutable borrows
Rust phân biệt hai loại reference:
- Immutable reference
&T: chỉ đọc. - Mutable reference
&mut T: sửa được, cầnlet mut s = ....
Quy tắc quan trọng: nếu có một mutable reference đến giá trị, thì không được có bất kỳ reference nào khác đến giá trị đó cùng lúc. Hai lỗi phổ biến:
error[E0499]: cannot borrow `s` as mutable more than once at a time error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
Lifetimes (vòng đời)
Mỗi reference trong Rust đều có một lifetime — phạm vi hợp lệ. Đa số implicit, chỉ annotate khi có nhiều khả năng. Mục đích chính: ngăn dangling references.
Lỗi điển hình khi reference trỏ tới giá trị đã ra khỏi scope:
error[E0106]: missing lifetime specifier --> message: "does not live long enough"
Ownership ngăn bug bộ nhớ
Nhờ quy tắc compile-time, Rust ngăn được toàn bộ class lỗi bộ nhớ phổ biến:
- No use-after-free: reference luôn bảo đảm trỏ tới giá trị hợp lệ.
- No data races: “một mutable ref HOẶC nhiều immutable ref” — không có hai nơi cùng ghi/đọc-ghi mâu thuẫn.
- No double free: owner duy nhất và move semantics chuyển quyền sở hữu.
- No null reference: Rust không cho phép null, giảm lỗi “null pointer exception”.
So sánh với Garbage Collection
So sánh ba cách quản lý bộ nhớ:
| Ngôn ngữ | Cơ chế | Ưu điểm | Nhược điểm |
|---|---|---|---|
| Java, Go, Python, JS | Garbage Collection | Không cần lo bộ nhớ | Runtime overhead, pause, không kiểm soát tốc độ |
| C, C++ | Cấp phát thủ công | Tốc độ tối đa | Dễ lỗi (use-after-free, double free, leak) |
| Rust | Ownership + Borrow Checker | An toàn như GC, tốc độ như C, zero runtime overhead | Học curve cao hơn |
Rust quảng bá: “no runtime or garbage collector, blazingly fast and memory-efficient.” — rust-lang.org
Kết luận
Ownership và borrow checker là trái tim của Rust. Chúng biến compiler thành cấu trúc bảo vệ bộ nhớ, cho phép lập trình viên viết code hiệu năng cao mà không phải hy sinh an toàn. Khi làm việc với Rust, hãy coi compiler như người đồng nghiệp nghiêm khắc — nó không bỏ qua lỗi, nhưng cũng không bao giờ gây bug lúc runtime.
