4.6 Naming Conventions: snake_case, SCREAMING_SNAKE_CASE

Right, let’s talk about naming things. It’s one of the two hard problems in computer science, the others being cache invalidation and off-by-one errors. But unlike cache invalidation, naming is something you have complete control over, and doing it well is the first step toward writing code that doesn’t make you want to claw your eyes out six months later. Rust has a few hard rules and a lot of strong conventions. The compiler will enforce the rules; the linter (clippy) will gently (or not-so-gently) suggest you follow the conventions. And you should listen. Conventions exist so that any Rustacean, anywhere, can open your code and immediately understand its structure without a Rosetta stone. It’s a shared language of clarity.

4.5 Static Variables: 'static Lifetime and Global State

Right, let’s talk about static. This is where we graduate from playing in the sandbox to juggling chainsaws. It’s incredibly powerful, occasionally necessary, and if you get it wrong, the resulting segfault will feel deeply personal. A static variable is essentially a global variable. I know, I know. You’ve heard horror stories about global state. Those stories are true. But in systems programming, sometimes you need a single, shared resource, and Rust, being the brilliant control freak it is, gives you a way to do it that’s almost safe. The key is the 'static lifetime.

4.4 Constants: const and Their Differences from let

Alright, let’s talk constants. You’ve met let, you’ve seen how it lets you change your mind (mutability), but sometimes you just need to lay down the law. You need a value that is absolute, unchanging, and resolute. You need a const. This isn’t a suggestion; it’s a declaration. When you define something with const, you are making a promise to the compiler and to every future developer (including future you, at 2 AM) that this value will not change. It is set in digital stone. The compiler, being a wonderfully pedantic enforcer of rules, will hold you to that promise with extreme prejudice.

4.3 Shadowing: Reusing a Name With a New Binding

Alright, let’s talk about shadowing. This is the part where you get to be a bit of a magician, or maybe a petty bureaucrat who just re-labels the filing cabinet. It lets you declare a new variable with the same name as a previous one. The old variable isn’t gone; it’s just… inaccessible. We’ve effectively shadowed it. Think of it like this: you have a variable x sitting on a shelf. You declare a new let x a few lines down. This isn’t modifying the first x. Oh no. This is you putting a brand new box, also labeled x, directly in front of the old one. From that point on in your code, whenever you reach for x, you get the new box. The old one is still there, perfectly intact, but completely hidden behind the new one. If the new x goes out of scope—say, we’re inside a block that ends—the new box is taken away, and suddenly the original x on the shelf is visible again. It’s been there the whole time.

4.2 mut: Opting Into Mutability

Right, let’s talk about mut. It’s the little three-letter keyword that causes a disproportionate amount of confusion for newcomers. Here’s the secret: Rust isn’t being difficult; it’s just making you be honest. By default, every variable you bind is immutable. It’s a promise that once you give a value a name, that name will always refer to that same value. It’s a fantastic default because it’s how you reason about code—you see let x = 5; and you know, for a fact, that x will be 5 until the end of its scope. No spooky action at a distance.

4.1 let Bindings: Immutable by Default

Let’s start with the most fundamental way to bring a value into existence: the let binding. You’ll use this thousands of times, so it’s crucial to get it right. The most important thing to know, and the thing that trips up almost every newcomer from other languages, is this: in Rust, a variable is immutable by default. When you write let x = 5;, you’re not creating a “variable” in the classic, C-style sense where it’s a named box you can put new things into whenever you want. You’re creating an immutable binding. The name x is now permanently tied to the value 5. It’s a contract. You can look, but you can’t touch. Try to break this contract and the compiler will swat you down with the gentle force of a freight train.

— joke —

...