Quyền sở hữu trong Rust
Hiểu ownership, quy tắc khiến Rust an toàn bộ nhớ không cần garbage collector: move, copy, clone và drop.
Bài thứ năm trong loạt Rust cơ bản. Ownership là ý tưởng đặc trưng nhất của Rust và là lý do nó an toàn bộ nhớ mà không cần garbage collector.
Các quy tắc#
- Mỗi giá trị trong Rust có một owner.
- Chỉ có thể có một owner tại một thời điểm.
- Khi owner ra khỏi phạm vi, giá trị bị hủy.
fn main() {
let s = String::from("hello");
println!("{s}");
} // s ra khỏi phạm vi; bộ nhớ được giải phóngrustNgữ nghĩa move#
Gán giá trị cho biến khác sẽ di chuyển quyền sở hữu — biến cũ không dùng được nữa:
let s1 = String::from("hello");
let s2 = s1;
// println!("{s1}"); // lỗi: giá trị đã bị di chuyển
println!("{s2}"); // okrustChuỗi không bị sao chép; dữ liệu và quyền sở hữu chuyển sang s2. Đây là lý do Rust không có lỗi dùng-sau-khi-giải-phóng.
Kiểu Copy#
Kiểu nhỏ có chi phí sao chép rẻ sẽ được sao chép, không bị move. Chúng implement trait Copy:
let a = 5;
let b = a; // a vẫn dùng đượcrustSố nguyên, số thực, boolean và char là Copy. String và Vec thì không.
Clone#
Để sao chép giá trị cấp phát trên heap, gọi .clone() một cách tường minh:
let s1 = String::from("hello");
let s2 = s1.clone();
println!("{s1} {s2}"); // cả hai đều hợp lệrustclone tạo bản sao sâu. Lời gọi tường minh làm lộ rõ chi phí.
Ownership và hàm#
Truyền giá trị vào hàm sẽ move nó; trả về sẽ move nó trở lại:
fn take_and_return(s: String) -> String {
s
}
fn main() {
let s = String::from("hi");
let s = take_and_return(s); // move vào, rồi move ra
}rustOwnership và phạm vi#
Giá trị bị hủy khi phạm vi của owner kết thúc. Dọn dẹp theo phạm vi nghĩa là tài nguyên — không chỉ bộ nhớ — được giải phóng tự động.
Vì sao quan trọng#
Ownership cho phép trình biên dịch chứng minh không có use-after-free, double-free, và con trỏ treo — những lỗi ám ảnh C và C++. Bạn viết code bình thường và trình biên dịch thực thi sự an toàn.
Kết luận#
Ownership: mỗi giá trị một owner, mặc định move, sao chép cho kiểu Copy, clone tường minh cho bản sao sâu. Bài tiếp theo trong loạt: tham chiếu và slice.