Learning Rust 🦀: 06 - Ownership: Intro
Tags: learning, rust, programming, development
Published: 2023-06-23 15:36:18

This is the first article in the series to discuss a Rust unique trait, **_Ownership_**. I'll split the topic into 2 parts to keep it light. So, let's start! 🤩  

>#### ⚠️ Remember!
You can find all the code snippets for this series in its [accompanying repo](https://github.com/FadyGrAb/rust-learning-series)  
If you don't want to install Rust locally, you can play with all the code of this series in the official [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021) that can be found on its official page. But for this one, you need a `cargo` installation on your machine (or a VM).

> ⚠️⚠️ The articles in this series are loosely following the contents of "The Rust Programming Language, 2nd Edition" by Steve Klabnik and Carol Nichols in a way that reflects my understanding from a Python developer's perspective.

⭐ I try to publish a new article every week (maybe more if the Rust gods 🙌 are generous 😁) so stay tuned 😉. I'll be posting "new articles updates" on my [LinkedIn](https://www.linkedin.com/in/fady-abdelmassih) and [Twitter](https://twitter.com/fadyGrAb).

## Table of Contents:
- [Memory management](#memory-management)
- [The Stack and the Heap](#the-stack-and-the-heap)
- [Rust Ownership](#rust-ownership)
- [Scopes in Rust](#scopes-in-rust)

### Memory management:
As briefly introduced in [the first article in the series](https://dev.to/fadygrab/learning-rust-1-intro-and-setup-5a77), a computer programing language has to manage the memory somehow for any computer program that is written in that language, a process called "memory management".  
Outside of the "Rust" world, this process is generally done either _manually_ (the programmer's responsibility) or using some sort of _garbage collection_ algorithm(s) (the programming language's responsibility). For Python, it uses _garbage collection_. Essentially, it's an algorithm to "automatically" identify _unused_ memory blocks by the program then "de-allocate" (free) them. In [this great article](https://stackify.com/python-garbage-collection/), you can read all about the details about _garbage collection_ in Python and I guess it will be similar in other languages too 🤷‍♂️.  
_**Manual**_ memory management, on the other hand, is totally the programmer's responsibility. The programmer has to _allocate_ (assign) memory to the program then _de-allocate_ (free) this memory when the program is done with it. This gives great power to the programmer and if done right, will make the program a lot more efficient and runs without any _garbage collection_ overhead. But this introduces new set of problems:  
- **If the programmer forgot to free memory**: It will result in something called _memory leak_ where the program is using too much memory overtime.
- **If the programmer frees the memory too soon**: This could cause the program to crash or data corruption which both are bad 😔. 

### The Stack and the Heap:
One more thing before we discuss Rust's _Ownership_ system and if you know what _The Stack_ and _The Heap_ are, you can skip this section. But for me this was a new thing! 🤓  
From a programming language's point of view, the computer memory is divided into two "_sub-systems_" (if we can call them that). One is an organized, known size and, queue-like system which is called _**The Stack**_. Entries in the stack must be of known size and are accessed on last-in-first-out basis. You can push (add) items to the stack and pop (delete) items from the stack too but you can't remove an item from the middle of it without popping the preceding items first. _Pushing_ to and _Popping_ from stack is faster than the heap.  
_**The Heap**_ is the less organized cousin of the _**Stack**_. Items can be of unknown sizes and can be allocated and de-allocated in any order. Pushing to _The Heap_ is slower than the _Stack_. When you allocate data to the _Heap_, you get a _pointer_ to this data because it's of unknown size.  
The main point here is that, accessing data in the _Stack_ is faster than the _Heap_ and the data in the _Stack_ must be of a known size at compile time in contrast to the _Heap_.

### Rust Ownership:
Rust has its own unique way to do _memory management_. It uses _**Ownership**_ which is the following 3 simple rules:
1. The value in Rust must have an _owner_.
2. Every value must have _only one owner at a given time_.
3. When the owner goes _out-of-scope_, the value is dropped.  

Following those rules, Rust has managed to enforce memory safety by avoiding the problems of _manual memory handling_ and avoided the use of _garbage collection_ which usually improves performance. You may wonder, "What exactly are those? scope and owner??!!". Don't worry, I'll talk about that, next 😉.  

### Scopes in Rust:
_Scope_ in Rust is the _range_ where this value (variable) is valid. A variable is valid starting from its _declaration_ till its current scope ends.
```rust
fn main() {
    // Start of "main" function scope.
    let x = 5;
    println!("Value of x from 'main' scope is {x}");

    {
        // Start of "internal" scope.
        let y = 10;
        println!("Value of y from internal scope is {y}");
        println!("Value of x from 'internal' scope again is {x}");
    } // End of "internal" scope.

    println!("Value of y from 'main' scope is {y}"); // Error: cannot find value `y` in this scope
    println!("Value of x from 'main' scope again is {x}");
} // End of "main" function scope
```
Go ahead and run this code. The program will panic due to this line `println!("Value of y from 'main' scope is {y}");` giving the following error:
```
cannot find value `y` in this scope
```
Which is pretty much the same as in Python and any other language. But this isn't all about _scopes_. As always with Rust, there are some differentiating caveats regarding scopes which we will explore in part 2.  

In this short article, we discussed some theory about Rust _**Ownership**_. In part 2, we will go deeper and build upon the topic of this article and start exploring the **_String_** type as an example to demonstrate the _**Ownership**_ concepts. See you then 👋.