In late 2022, after many years of using Go for all my personal projects, I started to pay attention to all the hype around Rust. My curiosity grew bigger and bigger as I read all these wonders about the language. Nevertheless I hesitated a lot before trying it out, because I loved the minimalism of Go so much and Rust was the very opposite on this regard.
That being said, my main gripes with Go annoyingly resisted going away, namely some pointer and concurrency bugs. Most of my programs are related to networking and often need optimisation and thus concurrency. This was what finally made me plunge into The Rust Programming Language book and learn the language.
It was a great journey lasting from the end of 2022 into early 2023. What an amazing book... Even if you don't want to learn Rust, I still recommend you to at least skim through some of the chapters, if you want to become a better programmer in any language. Although I have a degree in computer science for a long time, I still learnt with this book. Rust is a unique language in the sense that it tries to solve the problem of memory management in a novel way.
Languages usually address this problem in one of two ways. You either manage the memory manually, like in C/C++ or the language does it automatically for you using a garbage collector. Both approaches have pros and cons of course, manual management gives you fine grained control and performance at the cost of bugs if you forget to free memory, whereas garbage collected languages free you from such low level details at the expense of runtime performance penalties.
Rust does something hybrid. It does not have a garbage collector, but you don't need to manually free memory either. What it does is it uses a concept of ownership and move semantics that guarantees at compile time, that your program is free of any memory bugs. To achieve this the compiler enforces these three ownership rules:
- Each value in Rust has an owner.
- There can only be one owner at a time.
- When the owner goes out of scope, the value will be dropped.
You should read the Understanding Ownership chapter from the book to understand this, but essentially this allows memory to be freed safely without any explicit call by the programmer or any kind of garbage collection. This feels somewhat magical, but it's actually quite simply a static guarantee by the compiler. So what's the catch?
The catch is that those rules mean you need to rethink the way you program. You must almost ignore basic stuff you've taken for granted for years... Freely copying and sharing data, passing values around without thinking about who owns what, or relying on a runtime to clean up after you. Every function call, variable assignment, and data structure needs to respect ownership and borrowing rules. You end up thinking more about lifetimes, references, and moves than in most languages, which can feel restrictive at first.
However, all the time you need to spend thinking before your program compiles, which is going to be much longer in Rust, means you can be almost 100% sure the program will run without memory or concurrency bugs. This is because the compiler itself is really picky with the rules I mentioned and others. These rules mean you need to code correctly, whereas in other languages the compiler or interpreter is way more relaxed, accepting bad quality code with basic bugs.
Code correctness was the reason why I tried Rust and one of the main reasons why it became my favourite language, despite the steep learning curve. However, the amazing tooling (cargo is the best package manager in the world by far), ecosystem of libraries, explicit (even if often verbose) syntax, functional patterns and the pursuit of perfection by the maintainers was what really hooked me forever.