30 days of Rust - Day two - Ownership
Day 2 - Ownership
Today was an easy Sunday. I decided to study the concept of ownership. I am yet to fully wrap my head around it, but I'm going to share what I have learnt about it.
Coming from a Java background, I know that the JVM (Java Virtual Machine) has what is known as a garbage collector๐.
Whenever you create objects, they live in a part of memory known as the heap. Oftentimes, some objects are no longer needed. This is where the garbage collector ๐ comes in to delete those objects which are no longer in use and helps free up memory on your computer.
Quick example;
Famous rapper 2 Chainz changed his name from Tity Boi to 2 chainz. Nobody even remembers who Tity Boi is, not even Java.
//Object one
Artist tityBoi = new Artist();
//Object two
Artist twoChainz = new Artist();
// assign tityboy to twochainsโ
tityBoi = twoChainz;
So after reassigning tityBoi
to twoChains
, the object tityBoi previously referenced is no longer accessible. The garbage collector will realize this and that object will be toast ๐ in no time. Remember in Java, variable names are not objects, instead they are references to objects, the same way your street address is not your house but a reference to your house ๐ก.
Garbage Collection in Rust
Well there's no such. Rust is too clean ๐๐ฝ it doesn't need a garbage collector. Welcome to the concept of Ownership.
According to the documentation, there are 3 basic rules to this;
- Each value in rust has a variable called its owner.
- There can only be one owner at a time.
- When the owner goes out of scope, that value is dropped.
Quick example of how ownership works;
fn main(){
// genre comes into scope
let genre = String::from("Amapiano");
// genre moves into the function and out of scope
play_music(genre);
// genre is no longer valid here. Strange.
}
fn play_music(favorite_genre: String){
// favorite_genre comes into scope
println!("Now playing {}", favorite_genre);
// favorite_genre goes out of scope
}
The function play_music
takes the ownership of the genre
string Amapiano from the main function. If you try using genre
thereafter, the program will not run.
A quick fix in order to get the String back, would be to return favorite_genre
from play_music
. This would look like;
fn main(){
// genre comes into scope
let genre = String::from("Amapiano");
let genre_the_return = play_music(genre);
// output -> Amapiano will always be relevant.
println!("{} will always be relevant.", genre_the_return);
}
fn play_music(favorite_genre: String){
// favorite_genre comes into scope
println!("Now playing {}", favorite_genre);
// favorite_genre is returned
favorite_genre
}
How to overcome this strange behavior
Yet again, we find new concepts unique to Rust. Namely Referencing and Borrowing
A reference is an address to where an object stays ๐ก in memory. Unlike a pointer, a reference (like proof of residence) is guaranteed to point to a valid value of a particular type.
All we have to do is use the & symbol in order to have a reference e.g &genre
. So let's implement referencing to our first example.
fn main(){
let genre = String::from("Amapiano");
// a reference to java is sent to play_music
// similar to your rapper friend sending you a link to their EP on SoundCloud
play_music(&genre);
// genre is still in scope ๐บ๐ผ
println!("Musa Keys is the best artist in {}", genre);
}
fn play_music(favorite_genre: &String){
// favorite_genre is a reference to genre
println!("Now playing {}", favorite_genre);
}
Problem solved! Now favorite_genre
does not have ownership, just a reference. This means we also don't have to return the value in order to give back the ownership. What just happened is called Borrowing.
Conclusion
I think this is enough study for today. Time to digest what we just learnt ๐ง . Ownership is quite a strange and totally new concept to me but hey, we soldier on.
Please reach out to me on my social media accounts if you have any questions, comments or would like to do this challenge with me.