Rust: Ownership and Borrowing
Tags: rust, beginners, showdev
Published: 2020-01-14 05:32:59

I am learning [`Rust`](https://www.rust-lang.org/) and made some notes about `Ownership` and `Borrowing` concepts

> note that I am still coming to grips with these concepts while "fighting with the Rust borrow checker" at the same time ;)

### Ownership in Rust

Ownership = binding/association of value to a variable. The rules are:

- Only one owner at a time
- If the binding is "released" ownership is "gone" and data is "freed"

```
let p1 = Person::new(); //1
p2 = p1; //2

let p1 = Person::new();
do_something(p1); //out of scope
```

On line 2, `p1` will be freed - it's out of scope since it has transferred ownership to `p2`. Passing `p1` into another function also has the same effect

```
let p1 = Person::new();
p2 = p1;
println!("person {#:?}", p2)
println!("person {#:?}", p1) //compile error
```

That's the reason Rust does not allow you to use that value again. It enforces this at compile time using *borrow checker*


> **`Drop`**

> It is possible to implement the `drop` method from the `Drop` trait if custom cleanup logic is required. It will be automatically called by Rust when that value goes out of scope

Once a variable is out-of-scope i.e. its ownership has been relinquished, the Rust compiler will not allow you to use it again, since it needs to be "freed". This is also called `Moving` i.e. ownership of `p1` moved to `p2`

Ownership is applicable to heap data only, *not* stack data since it (stack data) is "copied", not "moved"

> **`Copy`**

> The `Copy` trait allows a value to be copied. All the primitive types (e.g. `i32`, `bool` etc.) implement `Copy` implicitly. Custom types (e.g. `struct`s) can implement `Copy` if all its components also implement `Copy` - to implement, you can either use `#[derive(Copy)]` or use an explicit implementation
 
### Ways of passing ownership 

... and keeping the compiler happy

- use the `clone()` method
- return from function
- passing a reference
- passing a mutable reference

**Use clone()**

Think of it as a `deep copy` like operation where it creates a separate copy of the data on the heap and points the new owner to it, leaving the old value untouched (or unmoved). Some types implement `Clone` trait by default (e.g. `String`), but you can mark your custom types as clone-able using `#[derive(Clone)]`


```
let p1 = Person::new();
let p2 = p1.clone();
do_something(p2);
println!("{:?}, p1); //works ok
```

**Return from function**

```
let p1 = Person::new();
do_something(p1);
...

fn do_something(p: Person) -> Person {
//logic
}

...

println!("p = {}",p1); //continue using p1 since ownership has been passed back

```

But this is just wired! You're forced to return something just because you want to keep the variable in scope


**Passing a reference**


```
let p1 = Person::new();
do_something(&p1);
println!("p = {}",p1); //continue using p1 since ownership has been was never passed on
...

fn do_something(p: &Person) {
//logic
}

...


```

The value of `p1` did *not move* - this is called `Borrowing`. `do_something` never got the ownership, since all we did was pass a reference to `p1` - notice the `&`

**Mutable References**

If you want `do_something` logic to update the name of the `Person` reference, you'll need to pass a mutable reference


```
let mut p1 = Person::new();
do_something(&mut p1);
println!("mutated info {}",p2)
...

fn do_something(p: &mut Person, new_name: String) {
   p.name = String::from(new_name);
}
...
```

Changes:

- Variable `p1` was declared as `mut` (mutable)
- Passed `&mut` to `do_something` instead of just `&` - signifies mutable reference
- `do_something` signature updated to `&mut` - signifies mutable reference

To dive in further, you can read up the following chapters from ["The Rust Programming Language"](https://doc.rust-lang.org/book/title-page.html) book

- [Chapter 4](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html) (ownership and borrowing)
- [Chapter 10](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html) (lifetimes)
- [Chapter 15](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html) (smart pointers)