Tutorials are great! But something is missing...

Francesco Ciulla - Aug 8 - - Dev Community

Tutorials are great.

They provide insights and help us learn new concepts.

But without practical application, you’ll likely forget what you’ve learned the day after. That’s why solving exercises is so important in programming. It forces your brain to engage, solve the problem with your hands, and truly grasp the concepts.

In many tutorials, including mine, the student’s approach is often PASSIVE: You watch the tutorial, read the article, clone the project, run it, it works, and you think you are making progress. And yes, you do make some progress, but it’s the same progress you make by watching someone else play poker. You understand the rules but miss out on what it means to play and learn the tactics to win.

That's why I created the Rust Workbook, a collection of exercises designed to help you learn Rust by doing. These exercises are carefully crafted to guide you through solving problems, building confidence, and reinforcing your understanding of Rust's core concepts.

In this article I want to give you a sneak peek into the Rust Workbook, show you how the exercises are structured, and provide an example to illustrate how they work.

Let’s dive in!

To truly benefit from this exercise, try to solve it independently before peeking at the solution (give yourself at least 30 minutes). That’s when the magic happens in your brain, and that’s when real learning occurs.

A Simple Exercise Example: Understanding Ownership in Rust
Let's examine an exercise focused on understanding Rust's ownership system to illustrate how the exercises are structured and how they guide you through the learning process.

Exercise 2.2: Ownership

Introduction

In Rust, every value has an owner, the variable that holds the value. When you move a value from one variable to another, the original variable can no longer be used. You can also borrow a value using the & operator, which allows you to access the value without transferring ownership.

Task

Declare a variable, move its value to another variable, and observe what happens when using the original variable. Then, use the & operator to borrow the value instead of moving it and see how this affects the original variable.

Instructions

  1. Open your terminal, run cargo new ownership, then cd ownership.
  2. Open src/main.rs in your IDE and replace its content with the code below.
fn main() {
    // Declare a variable with a string value
    let s1 = String::from("hello");

    // Move the value to a new variable (let s2 = s1)
    // Print both variables to see what happens

    // Borrow the value (let s2 = &s1)
    // Print both the original and the borrowed variable
}
Enter fullscreen mode Exit fullscreen mode
  1. Declare a variable with a string value using the let keyword.
  2. Move the value from this variable to a new variable using the = operator (let s2 = s1;).
  3. Try to print the original and the new variable to see what happens (you should encounter an error!).
  4. Instead, use the & operator to borrow the value from the original variable and assign it to a new variable (e.g., let s2 = &s1;).
  5. Print both the original and the borrowed variable to see the difference.
  6. Save the file and run cargo run in the terminal to see the result.

Good luck. If you need help, you can check this video

Once you have tried to solve the exercise, you can check the solution below.


Solution to Exercise 2.2: Ownership

Solution Overview

In this exercise, you were asked to explore Rust's ownership system by declaring a variable, moving its value to another variable, and observing what happens when you try to use the original variable. You also used the & operator to borrow the value instead of moving it, which allowed you to see how borrowing works in Rust.

Final Code

Here’s the code that achieves the task:

fn main() {
    // Declare a variable with a string value
    let s1 = String::from("hello");

    // Move the value to a new variable (s1 is no longer valid after this point)
    let s2 = s1;

    // Uncommenting the following line would cause a compile-time error because s1 has been moved
    // println!("s1: {}", s1); // This would cause an error

    // Print the new variable
    println!("s2: {}", s2);

    // Borrow the value from s2 using a reference
    let s3 = &s2;

    // Print both the original and the borrowed variable
    println!("s2: {}", s2);
    println!("s3: {}", s3);
}

Enter fullscreen mode Exit fullscreen mode

Program Output

When you run the program using cargo run, you will see this output in your terminal:

s2: hello
s2: hello
s3: hello
Enter fullscreen mode Exit fullscreen mode

Explanation

  • Ownership Transfer (Move): The line let s2 = s1; moves the String ownership from s1 to s2. After this move, s1 is no longer valid, and any attempt to use s1 would result in a compile-time error.

  • Borrowing with References: The line let s3 = &s2; creates a reference to s2, meaning s3 borrows the value of s2 without taking ownership. This allows both s2 and s3 to be used without transferring ownership.

  • Error Prevention: Rust's ownership system ensures memory safety by preventing multiple data ownership. Once a value is moved, the original variable can no longer be used, which prevents dangling references or double-free errors.

This exercise demonstrates how Rust's ownership model works, including how values can be moved between variables and how references can be used to borrow values without taking ownership.

It’s not about making things difficult—it’s about guiding you through the process, step by step, to help you understand how Rust manages memory safely.

Conclusion

This example highlights how the exercises in this workbook are designed. They may not be overly challenging, but they are structured to guide you through the learning process, helping you build a solid understanding of Rust's core concepts.

The book encourages you to think critically about your code and understand the underlying principles by taking a step-by-step approach.

Remember, the real value of this workbook lies in solving the exercises. Take your time, work through them methodically, and you’ll find that even simple exercises can lead to deep insights into how Rust works.

If you like this style and you want more exercises like the one above, check out the full Rust Workbook.
Rust workbook

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .