Ownership with Rust
Tags: rust
Published: 2019-08-22 07:50:07

---
title: Ownership with Rust
published: true
tags: rust
canonical_url: https://hellocode.dev/rust-ownership
cover_image: https://skitterphoto.com/photos/skitterphoto-1903-default.jpg
---

I've recently started learning the Rust programming language, I'm still very much a novice but thought it would be beneficial to attempt to explain some of its features here.

Ownership is one of the key features of Rust. Unlike other languages, Rust does not free unused memory with the use of a garbage collector or require the programmer to manage it manually. Instead, Rust uses a system of ownership to manage its values with rules which the compiler checks at compile time, meaning that you get the best of both worlds as your program is not slowed down at runtime by a garbage collector and you are not required to manage the memory usage yourself.

The basic idea of ownership is a simple one; every value is owned by a variable, it can only be owned by one variable at a time and when the variable goes out of scope, the value is dropped from memory.

## <svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Stack or Heap?

First, it's probably a good idea to talk about the two types of values that Rust deals with. Some values have a fixed size which is known at compile time and which will not change throughout the life of the program, for example _u32_. These values can be be stored on the stack and can be passed around freely without needing to worry about ownership. The other type of value is dynamic, it has a size which is not known at compile time and which could change whilst the program is running, such as a _String_. This second type is stored on the heap and a pointer to its location in memory is stored on the stack instead. The data on the heap can change size but its pointer will always remain the same size.

Ownership exists because of these dynamic values. Other languages encounter problems when pointers are left in the stack which reference memory that has already been reallocated; Rust does not have this problem. When a variable owns a value on the heap, no other variable can own it. It is possible to create pointers which reference the variable that owns the value and ownership can be moved to a different variable. When the variable that owns the value goes out of scope, the value is removed from the heap so that the memory can be reallocated.

To illustrate this, please take a look at the two examples below, the first uses _&str_ (size known at compile time) and the second _String_ (size not known at compile time).

### <svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>With &str

```rust
fn main() {
    let hello = "hello";
    println!("{} from the main function", hello);
    other(&hello);
    println!("{} again from the main function", hello);
}

fn other(greeting: &str) {
    println!("{} from the other function", greeting);
}
```

> hello from the main function hello from the other function hello again from the main function

### <svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>With String

```rust
fn main() {
    let hello = String::from("hello");
    println!("{} from the main function", hello);
    other(hello);
    println!("{} again from the main function", hello);
}

fn other(greeting: String) {
    println!("{} from the other function", greeting);
}
```

> error[E0382]: borrow of moved value: `hello` --\> src/main.rs:5:49 | 2 | let hello = String::from("hello"); | ----- move occurs because `hello` has type `std::string::String`, which does not implement the `Copy` trait 3 | println!("{} from the main function", hello); 4 | other(hello); | ----- value moved here 5 | println!("{} again from the main function", hello); | ^^^^^ value borrowed here after move

The compiler has told us that we've moved ownership of the value from the `hello` variable in the `main` function to the `greeting` variable in the `other` function and therefore it cannot be used again by the `main` function at _line 5_. The message also says "_move occurs because `hello` has type `std::string::String`, which does not implement the `Copy` trait_". I'll probably do a post about traits at some point so I won't go into them here but what the compiler is saying is that this is not a type that can be copied, hence why it has been moved. All types that can be stored on the stack can be copied, this is why the ownership rules do not apply to them; because their size is known, the performance cost of copying the values is not worth worrying about so that is what happens.

## <svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Cloning

This doesn't mean that we can't copy values on the heap though, cloning the value is one way we can make our code compile:

```rust
fn main() {
    let hello = String::from("hello");
    println!("{} from the main function", hello);
    other(hello.clone());
    println!("{} again from the main function", hello);
}

fn other(greeting: String) {
    println!("{} from the other function", greeting);
}
```

> hello from the main function hello from the other function hello again from the main function

Can you spot the difference? Now, on _line 4_, we call the `other` function with a clone of the value held by the `hello` variable. Obviously this is not the most efficient way to write your program, and it can be risky if you don't know the size of the values which are going to be getting cloned. Also, if your functions mutate the value in some way then this is not a good solution:

```rust
fn main() {
    let mut hello_from = Vec::new();
    hello_from.push("main");

    one(hello_from.clone());
    two(hello_from.clone());

    println!("hello from {:?}", hello_from)
}

fn one(mut hello_from: Vec<&str>) {
    hello_from.push("one");
}

fn two(mut hello_from: Vec<&str>) {
    hello_from.push("two");
}
```

> hello from ["main"]

Here, we're creating a Vector in which we want to collect the names of the functions which it has been passed to. Because we are using clone, each function is getting its own copy of the value which it is mutating, meaning that when we print the vector it only contains "main".

## <svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Moving

The first solution you might arrive at is to return the variable each time:

```rust
fn main() {
    let mut hello_from = Vec::new();
    hello_from.push("main");
    hello_from = one(hello_from);
    hello_from = two(hello_from);
    println!("hello from {:?}", hello_from)
}

fn one(mut hello_from: Vec<&str>) -> Vec<&str> {
    hello_from.push("one");
    hello_from
}

fn two(mut hello_from: Vec<&str>) -> Vec<&str> {
    hello_from.push("two");
    hello_from
}
```

> hello from ["main", "one", "two"]

In this example we are moving the ownership of the value to a new variable in each function scope. This is perfectly valid but in my opinion it has its downsides. First, it requires more code to be written, the `one` and `two` functions both now need to declare a return type and we need to overload the `hello_from` variable in the `main` function each time the value is returned _(lines 4 & 5)_. Secondly, I think it's easier to understand code when the owner of values stays in one scope; this is made possible with borrowing.

## <svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Borrowing

```rust
fn main() {
    let mut hello_from = Vec::new();
    hello_from.push("main");

    let hello_ref = &mut hello_from;
    one(hello_ref);
    two(hello_ref);

    println!("hello from {:?}", hello_from)
}

fn one(hello_from: &mut Vec<&str>) {
    hello_from.push("one");
}

fn two(hello_from: &mut Vec<&str>) {
    hello_from.push("two");
}
```

> hello from ["main", "one", "two"]

Here we create a mutable reference to our variable and pass that to the functions instead. Because it is a mutable reference we can push the values and they will be added to vector as if we had passed the vector itself, however the ownership of the value never leaves the `hello_from` variable in the `main` function.

## <svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>Some Caveats

As well as ensuring memory safety, Rust also protects us from race conditions with some rules around references. You can create as many immutable references as you wish, but you are not allowed to create more than one mutable reference at a time:

```rust
fn main() {
    let mut hello_from = Vec::new();
    hello_from.push("main");

    let hello_ref1 = &mut hello_from;
    let hello_ref2 = &mut hello_from;
    one(hello_ref1);
    two(hello_ref2);

    println!("hello from {:?}", hello_from)
}

fn one(hello_from: &mut Vec<&str>) {
    hello_from.push("one");
}

fn two(hello_from: &mut Vec<&str>) {
    hello_from.push("two");
}
```

> error[E0499]: cannot borrow `hello_from` as mutable more than once at a time --\> src/main.rs:6:26 | 5 | let hello\_ref1 = &mut hello\_from; | --------------- first mutable borrow occurs here 6 | let hello\_ref2 = &mut hello\_from; | ^^^^^^^^^^^^^^^ second mutable borrow occurs here 7 | one(hello\_ref1); | -------------- first borrow later used here

You are also not allowed to create a mutable reference whilst there are already one or more immutable references:

```rust
fn main() {
    let mut hello_from = Vec::new();
    hello_from.push("main");

    let display_ref = &hello_from;
    let hello_ref = &mut hello_from;
    one(hello_ref);
    two(hello_ref);

    display(display_ref)
}

fn one(hello_from: &mut Vec<&str>) {
    hello_from.push("one");
}

fn two(hello_from: &mut Vec<&str>) {
    hello_from.push("two");
}

fn display(hello_from: &Vec<&str>) {
    println!("hello from {:?}", hello_from)
}
```

> error[E0502]: cannot borrow `hello_from` as mutable because it is also borrowed as immutable --\> src/main.rs:6:25 | 5 | let display\_ref = &hello\_from; | ----------- immutable borrow occurs here 6 | let hello\_ref = &mut hello\_from; | ^^^^^^^^^^^^^^^ mutable borrow occurs here ... 10 | display(display\_ref) | --------------- immutable borrow later used here

But the compiler can tell when no further changes can be made via a mutable reference and allows you to start creating immutable references again!

```rust
fn main() {
    let mut hello_from = Vec::new();
    hello_from.push("main");

    let hello_ref = &mut hello_from;
    one(hello_ref);
    two(hello_ref);

    let display_ref = &hello_from;
    display(display_ref)
}

fn one(hello_from: &mut Vec<&str>) {
    hello_from.push("one");
}

fn two(hello_from: &mut Vec<&str>) {
    hello_from.push("two");
}

fn display(hello_from: &Vec<&str>) {
    println!("hello from {:?}", hello_from)
}
```

> hello from ["main", "one", "two"]

* * *

So that's my first post on Rust, I hope it was useful (and correct!), all being well I intend to write a couple of these as I find that in doing so really helps to increase my own understanding and if they can help somebody else at the same time then that's even better. If you've got any comments then let me know on Twitter. 😃