Ownership, References, Borrowing and Lifetimes in Rust
hardcore
18
Rust
27
White

Giang Nguyen viết ngày 06/10/2016

1. Ownership

Ownership là gì ?

Nếu tôi có một quyển sách và tôi quyết định cho bạn quyển sách, vậy là quyền sở hữu quyển sách đó tôi đã trao cho bạn, nếu sau này muốn dùng lại thì có được không ? Điều đó phụ thuộc vào chủ nhân của nó.

    fn foo() {
        let v = vec![1, 2, 3];  
    }

Xét hàm foo trên, khi biến v vào trong scope thì một vector sẽ được tạo ở stack và được cấp phát một vùng nhớ. Khi kết thúc hàm foo thì Rust sẽ clean biến v trên, cũng như delete vùng nhớ đã được cấp phát cho vector.

Move semantics

Rust ensures that there is exactly one binding to any given resource

    let v1 = vec![1, 2, 3];
    let v2 = v1;

Đối với đoạn code trên nếu tôi không giải thích thêm thì chúng ta cứ nghĩ rằng oh! đâu có gì đặc biệt đâu. Cũng không có gì đặc biệt thật, nếu chúng ta muốn in ra biến v1 thì sao ?

    let v1 = vec![1, 2, 3];
    let v2 = v1;
    println!("{:?}",v1);

nếu chúng ta chạy bằng ý nghĩ thì nó sẽ ra v1, nhưng thực sự thì không phải vậy, lúc này thì vùng nhớ của v1 đã bị move sang một chổ khác đó là v2. Khi compile code trên thì chúng ta sẽ nhận được thông báo lỗi:

 error[E0382]: use of moved value: `v1`
 --> src/main.rs:4:22
  |
3 |     let v2 = v1;
  |         -- value moved here
4 |     println!("{:?}", v1);
  |                      ^^ value used here after move

Nếu chúng ta truyền vector đó vào một function thì sao ?

fn take_ownership(v: Vec<i32>) {}
fn main() {
    let vec: Vec<i32> = vec![1, 2, 3];
    take_ownership(vec);
    println!("{:?}", vec);
}

Lúc này thì function take_ownership sẽ là người sỡ hữu vec sau khi function take_ownership kết thúc thì Rust sẽ clean vec và delete vùng nhớ đã được cấp cho vec nên khi compile ra vẫn nhận được lỗi tương tự như trên:

error[E0382]: use of moved value: `vec`
 --> src/main.rs:5:22
  |
4 |     take_ownership(vec);
  |                    --- value moved here
5 |     println!("{:?}", vec);
  |                      ^^^ value used here after move

Quay trở lại những ví dụ trên nếu chúng ta nhìn kỹ thông báo lỗi thì chúng ta sẽ thấy được một dòng lỗi khá thú vị:

note: move occurs because `vec` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait

What is Copy trait ?

Khi mà ownership được chuyển từ nơi này sang nơi khác :troll:, thì chúng ta không thể dùng được giá trị ban đầu khi được khai báo. Tuy nhiên nếu một type mà implement Copy trait thì ownership sẽ khác.

Ví dụ:

let v = 1;
let v2 = v;
println!("{}", v);

Khi compile chúng ta sẽ thấy được output là 1. Nếu khi báo tường minh hơn thì là

let v: i32 = 1;
let v2: i32 = v;

Lúc này thì v có type là i32, mặc định thì i32 sẽ implement Copy trait, nên đoạn code trên là chỉ copy value thay vì move.

Return ownership ?

Chúng ta có thể nhận ownership và trả về ownership với function

fn take_ownership(v: Vec<i32>) -> Vec<i32> {
    v // hey không có dấu ; ở cuối nha
}
fn main() {
    let vec: Vec<i32> = vec![1, 2, 3];
    let v: Vec<i32> = take_ownership(vec);
    println!("{:?}", v);
}

Kết luận:

Với ownership Rust đã làm cho chương trình của chúng trở nên safety. Bài viết này giới thiệu cơ bản về ownership, bài viết sau sẽ đi hết phần còn lại trong 3 phần quan trọng của Rust: ownership, references and borrowing, lifetimes

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Giang Nguyen

20 bài viết.
34 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
30 5
(Ảnh) Hai ngày nay mình đã tìm hiểu về Amazon S3, Cloudfront và Letsencrypt để xây dựng 2 trang web static, thứ nhất là trang chủ của (Link) và t...
Giang Nguyen viết gần 2 năm trước
30 5
White
9 0
Đôi dòng về ID3 (Ảnh) Nếu bạn nào chưa biết thì có thể đọc phần này, hoặc biết rồi thì có thể next tới phần kế tiếp nhé. 1. Giới thiệu Như hì...
Giang Nguyen viết hơn 1 năm trước
9 0
White
8 0
Type Result Type trên dùng để làm gì? Result được dùng cho những trường hợp chúng ta muốn return lại một giá trị nào đó (Ok) hoặc propagating erro...
Giang Nguyen viết hơn 1 năm trước
8 0
Bài viết liên quan
White
3 3
Hôm nay tự viết lại cái note này về quá trình học Rust, xem như là tự giúp mình nhớ sâu và rõ hơn về Rust. Note này sẽ ngắn gọn hơn bản (Link). Sơ...
Giang Nguyen viết gần 2 năm trước
3 3
White
0 0
fn plus_5(x: Option) i32 { x.unwrap_or(0) + 5 } fn main() { assert_eq(15, plus_5(Some(10))); } Compile không lỗi, thay đổi chút xíu nhỏ, ...
Giang Nguyen viết 2 năm trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
20 bài viết.
34 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!