In this episode I finally finish the guessing game from the book "The Rust Programming Language" by adding a loop to allow multiple guesses.

I'm doing a series of 25 minute sessions where I try to get familiar with the Rust programming language. The blogposts in these series are the notes I took of the lessons learned along the way.

Warning to the reader: As always in this series, these are notes I take as I'm learning. They reflect my current understanding and may be incorrect!

Looping

I was expecting a while loop, based on my experience with other languages. For example:

while (x != 1) { ... }

This would execute the code inside the brackets ({ and }) until x was no longer equal to 1.

But instead, the book suggests using a loop statement:

loop {
   ...
}

This runs the code in the brackets until that code tells it to stop, using a break statement.

In the match where the result is evaluated we execute the break statement if the guess was correct:

match guess.cmp(&secret_number) {
    Ordering::Less => println!("Too small."),
    Ordering::Greater => println!("Too big."),
    Ordering::Equal => {
        println!("You win!");
        break;
    }
}

I presume while isn't used, because variables are typically not mutable. The variable I check the while condition on (like x != 1) requires x to be mutable. Maybe there is a while statement and I while learn about it later.

read_line can append

Originally, I made the mistake of leaving the following statement outside of the loop:

let mut guess = String::new();

Then every time the player entered a guess the value was appended to the existing guess:

Please input your guess.
5
You guessed: 5

Too small.
4
You guessed: 5
4

3
You guessed: 5
4
3

This teaches me that if you use io::stdin().read_line with a mutable String variable, whatever the user inputs is appended to the existing string.

Note that this was only possible because my parse call now also handles the Err result by executing continue.

let guess: u32 = match guess.trim().parse() {
    Ok(num) => num,
    Err(_) => continue,
};

Match executes code

The match code for the parse call showed something interesting too.

At first, I thought a match would produce a value:

Ok(num) => num,

This would read as: If "Ok" then pass num as the result of the match. Which is actually also what it does.

But considering this:

Err(_) => continue,

I would read this as: If "Err" then pass continue as the result of the match. But that is not at all what happens.

It actually says: If "Err" then execute the following statement and the result of that statement is the result of the match.

Path statement?

The above means, for the first statement Ok(num) => num, the result of the match statement would be num.

This implies that a line with the following statement would be a valid statement:

`guess;`

Assuming guess is an existing variable.

And it is actually valid and it compiles. Although it does produce a rather cryptic warning: path statement with no effect

2018-08-31-00_04_45-Window

I can understand it warns about a useless statement, because it has no side-effects. But what I don't understand is what a path statement is. I've googled around for the term but haven't found anything. So if somebody can point me in a direction that would be super nice.

Conclusion

This was a quick session, but still I've learned that a match statement actually executes code.

I've also learned that read_line can append new text to an existing mutable String.

And finally, I've learned the important loop statement.

Next up in the book are no longer tutorials, so my way of working will have to change a little I think. We'll see!