Rust 所有权理解

Understanding OwnerShip

1. What Is Ownership?

​ Rust’s central feature is ownership.

1.1 Why need it?

Rust uses a third approach: memory is managed through a system of ownership with a set of rules that the compiler checks at compile time.
It’s an approach to manage the way they use a computer’s memory while running.

Managing heap data is why ownership exists can help explain why it works the way it does.

1.2 Concept

Ownership Rules:

  • Each value in Rust has a variable that’s called its owner.
  • There can only be one owner at a time.
  • When the owner goes out of scope, the value will be dropped.

2. OwnerShip Explanation

2.1 Stack and Heap

  1. These types are all stored on the stack and popped off the stack when their scope is over.
  • Scalar Types: Integers, floating-point numbers, Booleans, and characters
  • Compound Types: Tuples and arrays
  1. Complex data types (such as String)

     {
            let s = String::from("hello"); // s is valid from this point forward
    
            // do stuff with s
     }                                  // this scope is now over, and s is no
          
    

    When a variable goes out of scope, Rust calls a special function for us. This function is called drop, and it’s where the author of String can put the code to return the memory.

    String Type is mutable, growable. So we need to allocate an amount of memory on the heap.

2.2 Ways Variables and Data Interact: Move

  • Integer (Allocated in Stack)

    let x = 5;
    let y = x;
    

    let y = x make a copy of the value in x and bind it to y, and these two 5 values are pushed onto the stack.

  • String (Allocated in Heap)

    Tips: String type is made up of three parts:

    This group of data is stored on the stack, but ptr is a pointer to the memory in heap that holds the contents of the string.

    let s1 = String::from("hello");
    let s2 = s1;
    
    println!("{}, world!", s1); //error
    // 'let s2 = s1' means rust considers s1 to no longer be valid 
    //  therefore, Rust doesn’t need to free anything when s1 goes out of scope.
    

    ​ When we assign s1 to s2, the String data is copied, meaning we copy the pointer, the length, and the capacity that are on the stack, but we do not copy the data on the heap that the pointer refers to.

    ​ In this example, we would say that s1 was moved into s2

    ​ The data representation in memory looks:

2.3 Clone

Here’s an example of the clone method in action, it’s like Deep Copy in C++.

The heap data does get copied, and s2 will have the memory in heap that holds the contents of the string.

    let s1 = String::from("hello");
    let s2 = s1.clone();

    println!("s1 = {}, s2 = {}", s1, s2);

2.4 Stack-Only Data: Copy

	let x = 5;    
	let y = x;    
	println!("x = {}, y = {}", x, y); 

After let y=x, x is still valid and wasn’t moved into y.

The reason is that types such as integers that have a known size at compile time are stored entirely on the stack,

2.4 Ownership and function

fn main() {
    let s1 = gives_ownership();         // gives_ownership moves its return
                                        // value into s1

    let s2 = String::from("hello");     // s2 comes into scope

    let s3 = takes_and_gives_back(s2);  // s2 is moved into
                                        // takes_and_gives_back, which also
                                        // moves its return value into s3
} // Here, s3 goes out of scope and is dropped. s2 goes out of scope but was
  // moved, so nothing happens. s1 goes out of scope and is dropped.

fn gives_ownership() -> String {             // gives_ownership will move its
                                             // return value into the function
                                             // that calls it

    let some_string = String::from("hello"); // some_string comes into scope

    some_string                              // some_string is returned and
                                             // moves out to the calling
                                             // function
}

// takes_and_gives_back will take a String and return one
fn takes_and_gives_back(a_string: String) -> String { // a_string comes into
                                                      // scope

    a_string  // a_string is returned and moves out to the calling function
}

​ When a variable that includes data on the heap goes out of scope, the value will be cleaned up by drop unless the data has been moved to be owned by another variable.

全部评论

相关推荐

头像
不愿透露姓名的神秘牛友
03-13 14:57
点赞 评论 收藏
转发
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务