Lecture 5 - Guessing Game Part 1

Overview of today and Monday

  • Today: Part 1, in the terminal
  • Monday: Part 2, in VSCode

Learning objectives

By the end of class today you should be able to:

  • Use basic cargo commands to create projects and compile rust code
  • Add external dependencies to a project
  • Handle Rust's Result type with .expect()
  • Recognize common Rust compilation errors

Live guessing game demo

I might suggest drawing a diagram of the folder structure as we explore

















Key/new(ish) commands from the demo

cargo new guessing_game


nano Cargo.toml


open . # explorer . on Windows


cargo run


cargo build


cargo check


cargo run --release


./target/debug/guessing_game

Key files from the demo

Cargo.toml


Cargo.lock


.gitignore


src/main.rs


target/debug/guessing_game


target/release/guessing_game

Compiling review and reference

Option 1: Compile directly

  • put the content in file hello.rs
  • command line:
    • navigate to this folder
    • rustc hello.rs
    • run ./hello or hello.exe

Option 2: Use Cargo

  • create a project: cargo new PROJECT-NAME
  • main file will be PROJECT-NAME/src/main.rs
  • to build and run: cargo run
  • the machine code will be in : ./target/debug/PROJECT-NAME

Different ways to run Cargo

  • cargo run compiles, runs, and saves the binary/executable in /target/debug
  • cargo build compiles but does not run
  • cargo check checks if it compiles (fastest)
  • cargo run --release creates (slowly) "fully optimized" binary in /target/release

Back to the guessing game

We're going to add this to main.rs:

use std::io;

fn main() {
    println!("Guess the number!");
    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {}", guess);
}
cargo run

.expect() - a tricky concept

  • read_line() returns a Result which has two variants - Ok and Err

  • Ok means the operation succeeded, and returns the successful value

  • Err means something went wrong, and it returns a comment on what happened

  • If you use read_line() WITHOUT expect it will compile but warn you not to do that

  • If you use read_line() WITH expect and it says Ok the output will be the same (user input saved to guess)

  • If you use read_line() WITH expect and it says Err the program will crash and print what you wrote in .expect()

There are better ways of handling errors that we'll cover later

More on macros!

  • A macro is code that writes other code for you / expands BEFORE it compiles.
  • They end with ! like println!, vec!, or panic!

For example, println!("Hello"); roughly expands into

#![allow(unused)]
fn main() {
use std::io::{self, Write};
io::stdout().write_all(b"Hello\n").unwrap();
}

while println!("Name: {}, Age: {}", name, age); expands into

#![allow(unused)]
fn main() {
use std::io::{self, Write};
io::stdout().write_fmt(format_args!("Name: {}, Age: {}\n", name, age)).unwrap();
}

(which you can see will further expand!)

Adding a secret number

Adding to the toml:

[dependencies]
rand = "0.8.5"

Adding to main.rs

#![allow(unused)]
fn main() {
use rand::Rng;

let secret_number = rand::thread_rng().gen_range(1..=100);
println!("The secret number is: {secret_number}");
}

What did all that do

cat Cargo.toml 
cat Cargo.lock

cargo run
cargo run

Activity preview - let's break things!

Activity time

Activity 5

Debrief:

  • Let's make a list together - how many did we find?
  • Which error was the most confusing?
  • Which error message was the most helpful?
  • Did any errors surprise you?
  • What patterns did you notice in how Rust reports errors?

Wrapping up

  • Coffee slots this afternoon - stop by for 5 min if you want
  • Homework due Monday at 11:59pm
  • REMEMBER TO COMMENT what your commands do in Problem 1
  • Oh My Git - check you have "gold" borders (you did at least five at the command line)
  • There will ALSO be pre-work for Monday