Learning Rust: A clean start
Tags: rust, learning, beginners
Published: 2024-02-26 21:00:00

I've decided it's time to learn [Rust](https://www.rust-lang.org/) and in order to keep myself motivated I'm going to keep a record of how the learning is going here.

![Ferris the crab](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0xl5mafhbjgfuowu62t.png)

A little about me; I'm a web developer and have been for around 5 years, though I'd dabbled for years. I have experience with [Perl](https://www.perl.org/) and [PHP](https://www.php.net/) but my day to day is JavaScript/TypeScript be it through [NodeJS](https://nodejs.org/en) or [ReactJS](https://react.dev/). I want to learn Rust for no specific reason other than it's fun to learn new things.

My first port of call was to google `learn rust` which lead me to ["the book"](https://doc.rust-lang.org/book/). The book is a first steps guide written by the rust community for newbies (or Rustlings as they're called) to gain a 'solid grasp of the language'.

## Learning in public

I've chosen to document my Rust learning journey openly because I believe in the power of learning in public. By sharing my successes, challenges, and insights, I will reinforce my own understanding and hopefully provide a resource for others on a similar path. 

I've seen the value in this approach first-hand. I invite feedback, corrections and contributions from readers. Whilst I recognize that learning in public isn't for everyone, I've personally found it immensely beneficial and hope to inspire others to consider it. So, let's dive into the lessons.

## Lesson 1 'Getting started'

This lesson is broken down into 3 sections:

- Installation
- Hello, World!
- Hello, Cargo!

### Installation

I was relieved to see installation listed, I was worried I would have to look up how to install Rust. I'm on a Windows machine but decided I'd rather do my Rust learning in Linux, so I'll be using Ubuntu through WSL.

The install command looked easy enough it uses curl to download something and then pipes that through sh, so we can assume the downloaded item is a bash script of some kind.

```bash
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
```

Believe it or not this is where I made my first mistake. I saw the `Rust is installed now. Great!` message and moved on to the next lesson. Had I read on a little further I'd have seen that I needed to install the compiler separately.

> Linux users should generally install GCC or Clang, according to their distribution’s documentation. For example, if you use Ubuntu, you can install the build-essential package.

This was easily remedied though and I was back on track in no time.

```bash
sudo apt install build-essential
```

### Hello, World!

The next section is a staple of the dev community, the beloved "Hello, World!" example. 

![Hello world](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2navm68azq2jbk9mcsf.png)

There a few little bits I learnt here, functions are declared with the `fn` keyword, the entry point for any rust application is the `main` function within the `main.rs` file and the standard naming convention is to use underscores to separate words in function and filenames.

It was at this stage I discovered I didn't have a compiler installed, which I think is the real reason for simple sections like this, to make sure we're all set up correctly.

### Hello, Cargo! 

The previous section was very simple, this section is also very simple but introduces us to [cargo](https://crates.io/) which is Rust's package manager, as a JS dev my mind goes straight to NPM.

Cargo allows us to do a few cool things:

- name our packages.
- add package dependancies.
- run our program in one command.
- build our program with debug mode and release mode.
- check our program compiles without actually building it.

The example gets us to recreate our `Hello, World!` example but in the cargo way. The code is so simplistic it hardly feels worth showing but here it is.

```rs
fn main() {
    println!("Hello, world!");
}
```

## Lesson 2 'Guessing Game'

The second lesson doesn't have any subsections, the goal of the lesson is to program a guessing game where the user enters a number and we compare it to a randomly selected number, the game continues until the user has guessed the exact number.

We're still not doing anything ground breaking but the progress from printing static text to dynamically taking user input and returning a result is nice all the same.

### VSCode

It was at this point I decided that doing code changes in `nano` was not a great idea and I needed to open the project in VSCode. I added a few extensions to, hopefully, make development a little easier. These were [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer), [crates](https://marketplace.visualstudio.com/items?itemName=serayuzgur.crates) and [Even Better TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml). You can use any editor you like, I'm just used to VSCode.

![VSCode logo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rq9m8kkxv6milsxbv5zw.png)

### Making the game

Let's look at the game tutorial, it has us use cargo to make set up the project and very quickly introduces us to a few new concepts

- The `use` keyword.
- Mutable variables.
- Error handling.
- Cargo doc.

#### The `use` keyword

The `use` keyword allows us to pull in code from other libraries, as a web developer, I want to compare this to [import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import). By default Rust will have access to a set of items from the 'standard' library, this is called the prelude, but if you want access to anything else you'll have to use `use`.

In the example they give we do `use std::io;` which allows us to access the `io` namespace, this does feel a little weird though as we already had access to `std` meaning `std::io` is also accessible.

#### Mutable variables

In JavaScript land we have the concept of immutable and mutable variables, these are `const` and `let` where `const` is immutable and `let` isn't. Rust is a little different in that all variables are immutable unless specified otherwise, the variable keyword also is always `let`, or at least it is as far as I can tell so far.

```rs
let mut var1 = String::new(); // mutable
let mut var2 = String::from("Test String"); // mutable
let var3 = 6; // immutable
```

The book let's us know here that it will be returning to mutability in lesson 3. 

#### Error handling

We're introduced to two types of error handling `.expect` which doesn't attempt any sort of recovery but helpfully posts a message as the application crashes and `match`.

`Match` takes the `Result` from a function and then allows you to call a function based on the `Result`. In the example we're given `parse` and told it will either be `Ok` or `Err`, in the `match` we are able to define a function to be called on either of these cases. I assume that when we start dealing with more diverse functions match will be able to handle all `Result` types.

#### Cargo doc

This is my favourite part of Rust so far, I know it shouldn't be that exciting but I think it is. When you run the command `cargo doc` Cargo will scan through all the code you're using a generate help pages explaining functions and how to use them.

There isn't much explanation of this yet but I'm hoping these docs are generated from comments in the code, even if this isn't that case code bases that can self document is just so interesting to me.

### Wandering off the beaten track

At this point I was done with the first two lessons and decided to make a couple of changes to the guessing game. I extracted the game loop into its own function and I added an error message for failed parsing.

One thing I didn't like was the `magic` of this line.

```rs
let guess: u32 = match guess.trim().parse()
```

I didn't like that it felt like parse just magically knew what type it was aiming for. So I read the tooltip for parse in VSCode and it taught be about the `turbofish` syntax. I don't know if people don't like this syntax or if the writers of the book decided it was too complex for a beginner but to my eye is just made so much more sense. We tell parse what type we'd like and our `let` infers type from that rather than the other way around.

```rs
let guess = match guess.trim().parse::<u32>()
```

Here is the modified code.

{% embed https://replit.com/@andrewb05/Guessing-game %}

## Signing off

Thank you for coming on this journey with me. I plan to continue this series and cover the entire book. If you'd like to follow along, you can press the 'follow' button to be notified of new posts.

As I said earlier feel free to leave any feedback and if you're learning in public too please leave a link to your series in the comments so I can check it out.

Thanks so much for reading. If you'd like to connect with me outside of Dev here are my [twitter](https://twitter.com/Link2Twenty) and [linkedin](https://www.linkedin.com/in/andrew-bone-ba241b179/) come say hi 😊.