Ownership Concept in Rust
Tags: rust, tutorial, learning, programming
Published: 2020-07-31 19:34:19

*This post published on my blog [before](https://aligoren.com/ownership-concept-in-rust/)*

-----

Hi everyone. Before that, I wrote a post called [Control Flow Statements in Rust](https://dev.to/aligoren/control-flow-statements-in-rust-1mei).

Today we will see the ownership concept in Rust. Before I get started I have to say that it was really hard for me to understand.

Before starting, I’ll create a project with cargo;

```bash
cargo new understanding_ownership

cd understanding_ownership
```

## Introduction

Ummm, I don't know how can I start. There are three concepts in Rust. These are `ownership`, `borrowing`, and `lifetime`. You may be familiar with them. Rust's special feature is `ownership`.

## Ownership Concept

Developers are responsible for freeing memory in other low-level programming languages. When you finished your job you should free that resource(memory) you used and you give it back. Let me give you an example in the C programming language.

```c

char *some_str;

// We're allocating a space in memory
some_str = (char *) malloc(10);

// your logic here with some_str

// we're freeing some_str pointer and its resource
free(some_str);
```

**What would be if we didn't free it?**

In short, memory leaking will occur. You don't have to think about that in high-level programming languages. Because they probably will have a garbage collector mechanism. The garbage collector will do what it has to do.

### How Rust Handles That?

Rust doesn't have a garbage collector like C#'s garbage collector. Because it's a low-level functional programming language. But there are some features called `ownership`, `borrowing` and `lifetime`. In this post, we'll see the `ownership` concept.

Each variable is responsible for freeing resources. As we mentioned, when you're writing code in C, you responsible for that. If you're writing code in C# or Java, a garbage collector mechanism responsible for that.

A resource can have only one owner in Rust. However, some variables may don't have a resource. For example references.

### How Does This Mechanism work?

Let's assume we create a variable like that;

```rust
fn main() {
  let a = 10;
}
```

When you assign the variable `a` to the another;

```rust
fn main() {
  let a = 10;
  let x = a;
}
```

Or when you passed the variable `a` to a function as a parameter;

```rust
fn main() {
  let a = 10;
  some_function(a);
}
```

You transfer ownership of the variable `a`. We're calling this feature as `move` in Rust terminology. When you move a resource to a new one, the old one cannot be used anymore. Which means this avoids dangling pointer.

By the way, we should know that ownership only for heap-allocated types. For example;

```rust
// stack-allocated integer variable
let number = 30;

// we're copying value of 'number' variable to 'number2'. we're not moving it
let number2 = number;

println!("Number {} and Number2 {}", number, number2);
```

This will work because these are stack-allocated. Primitives like `i32`, `u64`, `f64`, or `bool` are small types. This means, copying them is fast and they don’t need to too much size in memory.

Now we'll see an example for the heap-allocated variable. The ownership mechanism will work here.

```rust
let number = Box::new(30);
println!("Number {}", number);

let number2 = number;
```

This won't work. It will throw an error like the `use of moved`. Why? As we mentioned before, variable ownership transferred to a function or a macro. In this case `println!` takes ownership of the `number` variable.

Let's see with an example;

```rust
fn box_value(value: Box<u8>) {
  println!("New ownership is here {}", value);
}

fn main() {
  let a_variable = Box::new(30);

  box_value(a_variable);

  // won't work
  println!("Value is {}", a_variable);
}
```

Because `a_variable` doesn't exist in this scope anymore. It doesn't point to the address you know before. Because we moved the resource of `a_variable`.

## What To Do Solve Ownership Problems?

### 1-) Create Scope Only Variables

You could create variable scopes using curly braces. The variable in the curly braces will work only inside of that scope.

```rust
fn box_value(value: Box<u8>) {
    println!("Value is {}", value);
}

fn main() {
    let a_variable = Box::new(30);
    
    {
        let a_variable = Box::new(30);
    
        box_value(a_variable);
    }
    
    println!("A variable {}", a_variable);
}
```

### 2-) Clone Variable

You could clone a heap-allocated variable. But it can be expensive.

```rust
fn main() {
    let a_variable = Box::new(30);
    
    println!("A variable {}", a_variable.clone());
    println!("A variable2 {}", a_variable);
}
```

### 3-) Returning Variables with Functions

You can transfer ownership of variables by returning values.

```rust
fn box_value(value: Box<u8>) -> Box<u8>{
    println!("Value is {}", value);
    
    value
}

fn main() {
    let a_variable = Box::new(30);
    
    let a_variable = box_value(a_variable);
    
    println!("A variable {}", a_variable);
    
    let a_variable = box_value(a_variable);
    
    println!("A variable2 {}", a_variable);
}
```

That’s all for now. If there is something wrong, please let me know. Because I still don't understand clearly it.

Thanks for reading.

## Resources

- [What is Ownership?](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)
- [Rust'ta Ownership Kavramı (Turkish)](https://canaltinova.com/blog/posts/rustta-ownership-kavrami/)