Recently, I have started to learn Rust. Why Rust you ask? Well, it's one of the best programming languages in each of these categories: performance, reliability, and productivity which we will discuss later. Also, coming from a Python/Javascript background, I thought it would be a challenge to learn a low level, statically typed language. Let's dive right into my initial thoughts on Rust and how it compares to other languages!
Learning Rust
Before I started learning Rust, I thought that it would be hard to get started and I was even wondering if I would be able to find good resources to learn Rust. I was wrong, big time. There are countless resources for learning Rust. I decided to take a Udemy Course and follow the offical Rust Programming Language book. The Udemy course and book were awesome! I would highly recommend looking at both when you're learning Rust. After that, I decided to play around with Rust, creating a simple command-line calculator application. To conclude, learning getting started with Rust is as simple as learning getting started with Python.
Rust is hard to learn
Rust is hard to learn because its a low-level programming language. If a programming language is considered a low level, it means that the language provides little difference from a computer's set architecture or in simpler terms it's closer to machine code (basically 0s and 1s). Especially coming from a high-level programming language background, Rust was not something I was used to. Learning about lifetimes, borrowing, and more (memory management) was something I didn't even have to look at in Javascript or Python. But being a low-level programming language comes with its perks.
Rust is extremely powerful
There is a reason why some programming languages (particularly targetted towards speed) are low level. To put it simply: since low-level languages are closer to machine code it's faster for them to compile to machine code and get executed then higher-level programming languages. Aside from being low-level, Rust also has some more very powerful features which make it memory safe, fast, and a productive environment. Let's have a look at these features.
Rust is fast
Rust is fast for two main reasons: it's statically typed and there is little to no overhead (garbage collection). I will get into garbage collection in a little bit but first I want to talk about how Rust is statically typed and compiled. Being statically typed and complied means that a type of a variable is known at compile time (before running your code). This means that instead of figuring out the type of your variable at run time, all Rust needs to do is execute your code. This is one less step needed at run time which makes Rust that much faster than other dynamically typed languages like Python or Javascript. Let's have a look at an example:
fn main() {
let message: &str = "Hello World";
println!("{}", message);
}
As you can see, in the main function, we are defining a variable which has a type of &str
. Instead of trying to figure out the type at compile-time, Rust already knows that our message is of type &str
. Let's have a look at the equivalent in Python:
def main():
message = "Hello World"
print(message)
main()
As you can see, we don't provide a type for our message variable hence the variable type is unknown until the program runs.
No garbage collection
Next, I want to talk about garbage collection. Most languages which are memory safe use a garbage collector to achieve this. What is a garbage collector? A garbage collector attempts to reclaim memory occupied by objects which are no longer used by the program. This prevents memory leaks and memory issues. This is how languages like Python, Javascript, or Java achieve memory safety. It's not all pros with a garbage collector. Having a garbage collector in your programming language makes it slow. Why is it slow you ask? For a garbage collector to collect its garbage, it stops the program, does its tasks, and then the program continues. As you can see, it stops to ensure memory safety which is why it is slow. Instead of implementing a garbage collector, Rust implements a concept called ownership. There are 3 rules to ownership in Rust:
- Each value in Rust has a variable that’s called its owner.
- There can only be one owner at a time.
- When the owner goes out of scope, the value will be dropped.
If one of these rules is not followed at any given time, the program will stop which eliminates all memory safety issues. Let's have a look at an example:
fn main() {
let var = 1;
{
let var1 = var;
}
println!("Var: {}, Var 1: {}", var, var1);
}
In this example, we are defining a variable called var
and variable called var1
. Since var1 is defined in another scope and its value is var, var is no longer valid (rule 3), hence this program results in an error.
The compiler is my best friend
The Rust compiler output is beautiful. It doesn't only tell you what the problem is, it tells you how to fix it. No more sleepless nights waiting for a response on StackOverflow, just implement what the compiler tells you what to do and no more bugs.
Should you learn Rust?
Rust is definitely something worth looking at. Even if you don't plan to use Rust for your future projects, for any developer coming from a higher-level programming language background to have a look at Rust. With that said, now I will be focusing on backend web development with Rust. Who knows, it might replace my Node.js backend (I'll keep you posted).
In conclusion, my experience thus far with Rust has been awesome. I would highly recommend playing around with Rust. Thanks for reading.
Henry
Top comments (24)
I've started learning Rust for the same reason, but because I'm coming from the same background of non-compiled languages (❤️ JS) and old habits are hard to give up, It's been a rough journey :-)
Does anyone have any hints for the code structure, for instance?
Hey, can you explain what do you mean by code structure exactly? 😅😅
For the projects I have done with Rust till now, I usually start with a rough separation of responsibility in different files, and as it grows ,keep refactoring and breaking large files into smaller, more modular files if needed. As compiler is so helpful, and testing is quite easy due to Cargo, the changes made are quite easy to verify for stability.
Hope this helps a little 😅🙂
Hey! Thanks for the reply!
I was wondering if there are architectural concepts on how to organize files for big projects in Rust.
In NodeJS, for instance, I like to create a
modules
folder and then I can manage features by adding or removing a reference from a barrel file.These
modules
can then be merged into a GraphQL or REST Server. But that server then will have a bunch ofresolver
functions.These functions take a fixed number of arguments, but they almost always have different types. And thus, defining a trait that all of the resolvers would comply with, renders impossible.
With this said, I understand why it should not work in a compiled language and that I'm stuck in the ways I used to do it.
So what are the Rust ways? :-)
Hey, there are some parallels between the NodeJS structure and possible Rust structure :
Say I have to make complex module ABC, which has to export multiple classes, functions and all. One would make a folder named abc, in which one can split files for each of the classes, maybe even one per functions, and export individual element from each file. Then one would define an index.js file for that folder, which will import from all files, and export elements, which can be directly used by import statements in other parts of a project. (#TodayILearnt it is called barrel file 😄)
Similarly, one can define in folder abc, multiple .rs files for each element, where they define that element (struct/function/trait etc.) as public , using
pub
. Then one would create mod.rs file, analogous to index.js, which will havepub use
statements instead of pair of import/export statements as in js.Then in the other files, one can use the
use
statements for importing the elements that are exported by that module.Note that this gets a little complected and/or different depending on type of the "project", as there is a differentiation between a binary project which can run on its own (an express server application) v/s a library project which is meant to be used as a library for other projects (express itself). One can also have a project that defines a library, and then also has a binary application in it, which uses the library. (Defining a middleware module for some processing, and using the same in an express server which is in the same project) Depending on the type, the path for
use
statement will slightly differ.One way would be to look at existing Rust projects and seeing how they have structures the files, that how I decided for my project (Library + application) : github.com/YJDoc2/8086-Emulator/. The file structure part in Readme might make it a bit more clear.
As far as GraphQL goes, I do not have any experience, but there seem to be some ways to do it, as there were several blogs showing how to use GraphQL with Rust, so it might be very much possible.
Hope this helped a little 😅
All said, I am also still learning Rust, so maybe there is another way to do it which I don't know, and someone else might reply, from which I can learn too. So, thanks for asking the question 😄
Thank you, will dig into it :-)
Apart from the "low level" and memory management aspect, there are two other things about Rust that I noticed when learning it:
a very sophisticated type system (supplemented by "macros"), which makes it possible to write "correct" software - that is, you can, to a certain extent, be assured that it will work if it compiles, even before you run it
strong support for FP concepts (Functional Programming) - many features in Rust reminded me a LOT of things I saw when learning Haskell
That's very true! I especially noticed that Rust is more a functional programming language than an object-oriented one. This really popped out because Rust has no classes. I also think that Rust has a very sophisticated type system and many more powerful features (macros, traits, etc). Thanks for reading!
Correct! Rust has no (or very limited) support for "classical OO", like class-based inheritance, but support for functional programming is extensive, even though Rust is not a "pure" FP language.
Rust does have interfaces and traits and so on, but doing conventional class/inheritance based OO programming (like you'd do in Java) is not a natural idiom in Rust - an experienced Rust programmer would generally prefer other approaches.
Exactly!
Good article. Thank you for posting.
I'm a beginner in
Rust
. To help more beginner, I have made a working case example with souce code in github. With an about three parts article, to leverage hello world.🕷 epsi.bitbucket.io/lambda/2020/11/2...
For example, concurrency in
Rust
is actually an easy thing to do. And also the code is almost as short as goroutine counterpart, as shown in below example:I hope this could help other who seeks for other case example.
That's a great article! Thanks for reading!
Hey, great article!
You might find the rustlings course useful to learn Rust , by hands on examples
github.com/rust-lang/rustlings
If you like to learn by Books, along with videos , check our Programming Rust by O'Reilly publication, it is really good.
Wow, what a great tool, I'll have a deeper look into it! Thanks for reading!
Good article!
I also just started to learn Rust.
Currently, I consider this language for my pet projects but maybe in the future, I will shift to Rust on regular work as well. Although as far as I see right now there is not much job related to Rust, maybe I'm wrong.
Since Rust became very popular recently their are fewer job opportunities than say C++. With that said, with more and more people learning about the power of Rust, more open source projects are written in Rust (e.g. Deno).
I really want to learn it for embedded device applications, as it would be so much nicer than C code. It's a lot to take in, however, so I keep losing motivation to push through and learn more :/
Trust me, once you get the fundamentals, Rust is the best programming language to work with (hence why its the most loved programming language 4 years in a row).
Some comments may only be visible to logged-in visitors. Sign in to view all comments.