Rust - Quyền sở hữu
Bộ nhớ cho một chương trình có thể được cấp phát như sau:
- Stack
- Heap
Cây rơm
Một ngăn xếp theo sau một cuối cùng trong thứ tự đầu tiên. Stack lưu trữ các giá trị dữ liệu mà kích thước đã biết tại thời điểm biên dịch. Ví dụ, một biến có kích thước cố định i32 là một ứng cử viên để phân bổ ngăn xếp. Kích thước của nó được biết tại thời điểm biên dịch. Tất cả các loại vô hướng có thể được lưu trữ trong ngăn xếp khi kích thước được cố định.
Hãy xem xét một ví dụ về một chuỗi, được gán một giá trị trong thời gian chạy. Kích thước chính xác của một chuỗi như vậy không thể được xác định tại thời điểm biên dịch. Vì vậy, nó không phải là một ứng cử viên cho phân bổ ngăn xếp mà là phân bổ đống.
Đống
Bộ nhớ heap lưu trữ các giá trị dữ liệu có kích thước không xác định tại thời điểm biên dịch. Nó được sử dụng để lưu trữ dữ liệu động. Nói một cách đơn giản, bộ nhớ heap được cấp cho các giá trị dữ liệu có thể thay đổi trong suốt vòng đời của chương trình. Heap là một vùng trong bộ nhớ ít được tổ chức hơn khi so sánh với stack.
Quyền sở hữu là gì?
Mỗi giá trị trong Rust có một biến được gọi là ownercủa giá trị. Mọi dữ liệu được lưu trữ trong Rust sẽ có chủ sở hữu được liên kết với nó. Ví dụ, trong cú pháp - cho age = 30, age là chủ sở hữu của giá trị 30 .
Mỗi dữ liệu chỉ có thể có một chủ sở hữu tại một thời điểm.
Hai biến không thể trỏ đến cùng một vị trí bộ nhớ. Các biến sẽ luôn trỏ đến các vị trí bộ nhớ khác nhau.
Chuyển quyền sở hữu
Quyền sở hữu giá trị có thể được chuyển giao bởi -
Gán giá trị của một biến này cho một biến khác.
Truyền giá trị cho một hàm.
Trả về giá trị từ một hàm.
Gán giá trị của một biến cho một biến khác
Điểm bán hàng chính của Rust as a language là tính an toàn về bộ nhớ của nó. Sự an toàn của bộ nhớ đạt được bằng cách kiểm soát chặt chẽ những người có thể sử dụng những gì và khi nào các hạn chế.
Hãy xem xét đoạn mã sau -
fn main(){
let v = vec![1,2,3];
// vector v owns the object in heap
//only a single variable owns the heap memory at any given time
let v2 = v;
// here two variables owns heap value,
//two pointers to the same content is not allowed in rust
//Rust is very smart in terms of memory access ,so it detects a race condition
//as two variables point to same heap
println!("{:?}",v);
}
Ví dụ trên khai báo một vectơ v. Ý tưởng về quyền sở hữu là chỉ một biến liên kết với một tài nguyên, v liên kết với tài nguyên hoặc v2liên kết với tài nguyên. Ví dụ trên đưa ra một lỗi - sử dụng giá trị đã di chuyển: `v` . Điều này là do quyền sở hữu tài nguyên được chuyển sang v2. Nó có nghĩa là quyền sở hữu được chuyển từ v sang v2 (v2 = v) và v sẽ bị vô hiệu sau khi di chuyển.
Truyền giá trị cho một hàm
Quyền sở hữu của một giá trị cũng thay đổi khi chúng ta chuyển một đối tượng trong heap tới một hàm hoặc một hàm.
fn main(){
let v = vec![1,2,3]; // vector v owns the object in heap
let v2 = v; // moves ownership to v2
display(v2); // v2 is moved to display and v2 is invalidated
println!("In main {:?}",v2); //v2 is No longer usable here
}
fn display(v:Vec<i32>){
println!("inside display {:?}",v);
}
Trả về giá trị từ một hàm
Quyền sở hữu được chuyển cho hàm sẽ bị vô hiệu khi quá trình thực thi hàm hoàn tất. Một cách giải quyết vấn đề này là cho phép hàm trả về đối tượng sở hữu trở lại trình gọi.
fn main(){
let v = vec![1,2,3]; // vector v owns the object in heap
let v2 = v; // moves ownership to v2
let v2_return = display(v2);
println!("In main {:?}",v2_return);
}
fn display(v:Vec<i32>)->Vec<i32> {
// returning same vector
println!("inside display {:?}",v);
}
Quyền sở hữu và các kiểu nguyên thủy
Trong trường hợp kiểu nguyên thủy, nội dung từ biến này được sao chép sang biến khác. Vì vậy, không có động thái sở hữu nào xảy ra. Điều này là do một biến nguyên thủy cần ít tài nguyên hơn một đối tượng. Hãy xem xét ví dụ sau:
fn main(){
let u1 = 10;
let u2 = u1; // u1 value copied(not moved) to u2
println!("u1 = {}",u1);
}
Đầu ra sẽ là - 10.