Rustlings Session 1: First Steps into Rust (Sections 0-6)

last updated by ewan datetime loading...

(datetime loading...)

View on WhiteWind or see the record at atproto.at

7 min read • 1,339 words


Well, I’ve finally done it. Before this, I knew next to nothing about Rust—like, I’d heard the name tossed around and maybe caught a snippet or two, but no real clue what it was about. After months of hearing about Rust from seemingly every corner of the programming world, I decided to dive in properly with Rustlings—the hands-on learning tool that throws you into the deep end with compiler errors and expects you to swim.

Spoiler alert: I survived. Mostly. You can see how I've done on my GitHub repository

The Setup

Before we get into the meat of it, a quick word about my setup. I'm running this on my M2 Mac mini with rustc 1.88.0, and honestly, the tooling experience has been refreshingly smooth compared to some other languages I've wrestled with. No mysterious dependency conflicts, no arcane PATH issues—just install and go. It's the sort of thing that makes you slightly suspicious, like when someone's being too nice to you.

The Rustlings exercises are brilliantly structured. Each one is broken, and your job is to fix it. It's like being a digital mechanic, except instead of oil-stained overalls, you're wearing confusion and mild panic.

Session 1: The Journey Through Sections 0-6

I knocked out the first batch of exercises—sections 0 through 6—in about 2.5 hours. That might sound quick, but let me assure you, those 2.5 hours contained enough "what the hell is a borrow checker?" moments to fill a small PhD thesis.

Section 0: Intro

The intro section is essentially Rust saying "hello world" in the most elaborate way possible. You print some ASCII art, learn about println! macros (note the exclamation mark—Rust is very excited about macros), and get your first taste of the compiler being both helpful and pedantic.

I added my own cheeky println!("hello world"); because, well, tradition is tradition, and some things are sacred.

Section 1: Variables

Ah, variables. Or should I say, "immutable bindings by default that you have to explicitly make mutable because Rust trusts you about as much as I trust my impulse to buy things on Amazon at 2 AM."

Coming from Python and TypeScript, where variables are variables and mutability is just assumed, Rust's approach felt like having a very polite but firm bouncer at every variable declaration. You want to change this value? You sure? Really sure? Alright then, add mut and we'll allow it.

The exercises here are straightforward enough—add let keywords, provide initial values, deal with type annotations. The compiler errors are genuinely helpful, which is both surprising and slightly unnerving. I'm used to error messages that read like cryptic poetry written by a spiteful ghost.

Section 2: Functions

Functions in Rust are... well, they're functions. But with type annotations. Lots of type annotations. Coming from languages where you can just wing it with parameter types, having to explicitly declare that num: i32 felt like being asked to show my working in a maths exam.

The syntax is clean though. fn function_name(parameter: type) -> return_type is logical once you get used to it. The exercises walk you through adding missing parameter types, return types, and fixing function signatures. There's a satisfying moment when you realize the compiler isn't just being difficult—it's genuinely trying to save you from yourself.

Section 3: If Statements

Control flow in Rust is blessedly familiar if you've used other C-style languages. The if statements work as expected, though Rust's insistence that every arm of an if expression returns the same type keeps you honest.

The exercises here involve implementing comparison functions and dealing with different return paths. Nothing groundbreaking, but it's a gentle introduction to Rust's expression-based nature. Everything returns something, even if that something is the unit type () (which is essentially Rust's way of saying "I've got nothing for you, mate").

Section 4: Primitive Types

This is where things get interesting. Rust has more number types than you can shake a stick at: i32, u64, f32, isize, usize... it's like someone looked at other languages and thought, "You know what we need? More precision in our indecision about what size numbers should be."

Arrays, tuples, slices—all the usual suspects are here, but with Rust's particular flavour of type safety. I particularly enjoyed the array slicing exercise, where you extract &a[1..4] to get elements at indices 1, 2, and 3. It's intuitive once you remember that ranges are exclusive at the end, which only took me three attempts to get right.

The tuple destructuring was nice too: let (name, age) = cat; feels clean and purposeful. Though I must admit, I got distracted by my own comment about furries. Old habits die hard, apparently.

Section 5: Vec

Vectors! The more flexible cousin of arrays, living on the heap and free to grow as needed. Coming from languages where lists/arrays are dynamic by default, the distinction between stack-allocated arrays and heap-allocated vectors took some getting used to.

The vec! macro is neat—a clean way to initialize vectors with values. The exercises walk you through creating vectors, iterating over them, and using methods like push() and map().

I particularly appreciated the comparison between manual iteration with a for loop and the functional approach with map() and collect(). The functional style feels more expressive, though I confess I found myself adding debug println! statements everywhere because old habits, etc.

Section 6: Move Semantics

And here we are—the famous (infamous?) Rust ownership system. This is where the training wheels come off and Rust reveals its true nature: a language that cares deeply about memory safety and will make you prove you understand the rules before it lets you play.

Move semantics, borrowing, the borrow checker—these are the concepts that make Rust both powerful and occasionally maddening. The exercises start simple (just add mut to make a variable mutable inside a function) but quickly escalate to dealing with ownership transfer and cloning.

The clone() method became my friend very quickly. Need to use a value in multiple places? Clone it. Don't want to think too hard about ownership right now? Clone it. It's the duct tape of Rust programming—not always the most elegant solution, but it gets you moving.

Reflections After Session 1

So, what do I think after my first proper encounter with Rust?

The Good:

  • The compiler is genuinely helpful. Error messages are clear and often include suggestions for fixes.
  • The type system feels solid. Once something compiles, you have reasonable confidence it'll work.
  • The tooling is excellent. Rustlings itself is a brilliant learning tool.
  • The concepts, while initially foreign, start to make sense with practice.

The Challenging:

  • Coming from garbage-collected languages, thinking about ownership and borrowing requires a mental shift.
  • The number of type annotations can feel verbose coming from more dynamic languages.
  • The borrow checker is clever but stern. It will reject code you think should work until you learn to think the way it thinks.

The Verdict: I'm cautiously optimistic. Rust clearly has opinions about how code should be written, and while those opinions can feel restrictive at first, they seem to come from a place of genuine concern for correctness and performance. It's like having a very knowledgeable friend who won't let you make certain mistakes—annoying in the moment, potentially lifesaving in the long run.

The learning curve is real, but it's not insurmountable. The exercises progress logically, and there are enough "aha!" moments to keep you motivated through the confusion.

What's Next?

I haven't looked at sections 7 and beyond yet, but I suspect they'll introduce more advanced concepts like structs, enums, error handling, and probably more exotic ownership scenarios. Part of me is curious, part of me is slightly terrified.

But that's the nature of learning something genuinely different, isn't it? The discomfort means you're growing, or at least that's what I tell myself when the borrow checker rejects my code for the fifteenth time.

I'll be back for Session 2 soon enough. The Rust journey continues.


Comments

Loading comments...