Alice, Bob, and Carol Take Ownership
Tags: rust, codenewbie, raii
Published: 2020-04-14 18:59:04

A thought exercise in Rust ownership system for noobs.

### Chapter 1: Move

```rust

let alice = String::from("happy");
let bob = alice;

// is alice still happy? NO.
// alice is now invalid.
// bob now has alice's livelihood.
println!("alice is {}", alice);

```

__In Rust, a value can always have *only one owner*__.

Let's return the happiness to `alice`.

```rust

// ERROR!
alice = bob;

```

__All variables are *immutable by default*__.

Therefore, `alice` will be sad forever.

Then `carol` comes along and asks `bob` if she could also be happy. `bob`, sunken in regret of killing `alice`, agree to try.

```rust

fn carol(v: String) {
    println("carol is {}", v)
}

fn main() {
    let alice = String::from("happy");
    let bob = alice;

    carol(bob);

    // bob is dead.
    println!("bob is {}", bob);

    // so is alice
    println!("alice is {}", alice);
}

```

`carol`, realizing the hard truth of life, stand holding happy until the end of _time_ (or _lifetime_ of `main`).

**"happy" String was *moved* from `alice` to `bob`, then to `carol`**.

### Chapter 2: Copy

```rust

let alice = "happy";
let bob = alice;

// Both can be happy!
println!("bob is {}", bob);
println!("alice is {}", alice);


```

Because Rust knows how big `"happy"`, `1`, `-20`, `0x08`, `3.1418` are beforehand, it simply creates a new copy for everyone.

**Simple fixed size types are not *moved*; They are *copied*.**

### Chapter 3: Clone

In **Chapter 1**, if both `alice` and `bob` were to be happy, bob could have `clone`d `alice`'s happiness.

```rust

let alice = String::from("happy");
let bob = alice.clone();

println!("bob is {}", bob);
// alice is still alive and well.
println!("alice is {}", alice);

```

When something is `clone`d, it summons an evil doppelganger from the computer's limbo called *the Heap*. If the thing is huge, it means twice the memory and time.

**It is costly to make everyone happy.**

### Chapter 4: Borrowing

In **Chapter 1**, what if `carol` could have turned back time and chosen to only take `happy` from `bob` for a while, and return it to him?

```rust

let alice = String::from("happy");

// happiness moves from alice to bob.
// bob is also mutable so he can later
// get his `happy` back from carol.
let mut bob = alice;

fn carol(v: String) -> String {
    // carol enjoys the happiness
    println!("carol is {}", v);
    // then returns it.
    v
}

bob = carol(bob);

// bob is fine and dandy
println!("bob is {}", bob);

```

**`carol` has to return the moved happiness so somebody else can use.**

But instead of always returning, which is forget-prone, `carol` could just borrow.

First, let's prove that when something is *moved*, it is gone forever, even after the last owner is dead.

```rust

let alice = String::from("happy");

// New scope
{
    let bob = alice;

    // bob owns happiness.
    println!("bob is {}", bob);

    // bob is going out of scope.
}
   
// ERROR! alice is invalid forever.
println!("alice is {}", alice);

```

To settle for a middle ground, `bob` *borrows* from `alice` instead.

```rust

let alice = String::from("happy");
{
    // bob borrows from alice.
    // alice still owns the happiness.
    // She just can't use it now.
    let bob = &alice;

    // bob enjoys happiness.
    println!("bob is {}", bob);

    // ERROR! alice tries to use happy
    println!("alice is {}", alice);

    // bob is out of scope, returning what
    // he borrowed automatically.
}
   
// alice's livelihood is back :).
println!("alice is {}", alice);

```

`carol` decides she better borrow from `bob` while he is at it.

```rust

fn carol(v: &String) {
    // carol enjoys the happiness she borrowed.
    println!("carol is {}", v);
    // carol is going out of scope.
} 

fn main() {
    let alice = String::from("happy");
    {
        let bob = &alice;

        // bob enjoys happiness.
        println!("bob is {}", bob);

        // while carol is borrowing, bob has to wait.
        // carol does not have to return ownership back to bob.
        carol(&bob)

        // bob now has the happiness because carol is done.
        println!("bob is {} again", bob);

        // bob is out of scope.
     }
   
     // alice can now be happy again, after bob and carol are done.
     println!("alice is {}", alice);
}

```

**Anyone can borrow taking a *reference* (`&`) to a thing, but the lender must outlive the borrower.**


### Chapter 6: Lifetime

In Rust, a borrowed *reference* has a *lifetime*.
 
```rust

fn carol<'carol_t>(v: &'carol_t String) {
    // 'carol_t is a lifetime of carol.
    // This reads "carol has a lifetime `carol_t`, 
    // and she will only borrow `v` that lives at 
    // least `carol_t` long.
}

```

A *lifetime* is the time and scope of when a referenced value is created until the end.

`carol` is hopeless at her pursue of happy-ness. So she gets into the loan business.

She creates an account with money inside and gives out to anyone who wants to borrow from her.

She uses reference so whoever borrows from her will always return the money when he/she dies.

```rust

// ERROR! 
fn carol() -> &i32 {
   let carol_reserve = 10;
   &carol_reserve
}

``` 

Alas, because `carol_reserve` has a short lifetime inside `carol`, it cannot be borrowed from anyone. :(

```rust

// With lifetime annotation revealed.
fn carol<'carol_t>() -> &'carol_t i32 {
    let carol_reserve: 'carol_t i32 = 25;
    let carol_reserve_ref: &'carol_t i32 = &carol_reserve;
    carol_reserve_ref

    // But 'carol_t finishes here.
}

// let's say `main` has a lifetime named `main_t`.
fn main<'main_t>() {

    // It is impossible for `broke_bob` to borrow
    // from `carol()` because he lives longer than
    // `carol_t`.
    // (He lives slightly after `main_t` and dies just before)
    let broke_bob<'bob_t> = &carol<'carol_t>();
}

```

The only way `carol` could have pulled this off is to borrow the amount from somewhere that lives longer than herself (`carol_t`) and `broke_bob` (`bob_t`). 

```rust

// `CENTRAL_RESERVE` lives for the entire lifetime
// of a program.
static CENTRAL_RESERVE: i32 = 1000_000_000;

fn carol(money: &i32) -> &i32 {
    money
}

fn main() {
    broke_bob = carol(&CENTRAL_RESERVE);
}

```

**The main point of lifetimes is to make sure a reference outlives whoever borrows it.**

<hr/>

If you're interested in my non-programming thoughts, you can [subscribe to my newsletter BETA School](https://joechasinga.substack.com/).

[![Joe Chasinga Newsletter BETA School](https://dev-to-uploads.s3.amazonaws.com/i/nhx7l8n1ufgeoqlc3pc7.png)](https://joechasinga.substack.com/)