By the end of this session you should be able to …
Result
typeif
, else
) and loops (loop
)Our goal is to implement a guessing game that:
cargo
is Rust’s package manager and build toolcargo new
creates a new project with the given namecargo run
both compiles and runs the projectcargo build
We will process a guess by:
main
function in src/main.rs
let
to create variableslet mut
for mutable variablestdin().read_line(&mut guess)
to get user inputguess
string&
indicates a reference to the variable&mut
is necessary, because references are immutable by defaultread_line
returns a Result
type (either Ok
or Err
).expect()
to handle errors and crash if an error occursprintln!
println!
with placeholders ({}
) for formatted outputrand
crate for random number generationuse
keyword to bring this crate into scoperand
crate to Cargo.toml
under [dependencies]
cargo build
will fetch and compile external dependenciescargo add
to add dependencies
cargo add rand
use rand::Rng;
brings the random number generator trait (Rng
) into scopethread_rng()
for random number generationuse std::cmp::Ordering;
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
cmp()
from the standard library to compare guess
with secret_number
cmp()
returns the Ordering
enum, which has values (Less
, Greater
, or Equal
)match
will match the appropriate arm of the enum, and print “Too small”, “Too big”, or “You win!”guess
is a string, but we want to compare it to an integertrim()
to remove unexpected whitespace from the stringparse()
to convert the string to an integeruse rand::Rng;
use std::{cmp::Ordering, io};
fn main() {
let secret_number = rand::thread_rng().gen_range(1..=100);
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
let guess: u32 = guess.trim().parse().expect("Please type a number!");
println!("You guessed: {}", guess);
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
}
loop
to allow repeated guessesEqual
branch of the enum using {}
break
statement to exit the loop when the guess is correctbreak
exits both the loop and the program.expect()
Err
enum.expect()
with match
to handle possibility of non-numeric inputErr
), ignore the guess and continue loopinguse rand::Rng;
use std::{cmp::Ordering, io};
fn main() {
let secret_number = rand::thread_rng().gen_range(1..=100);
loop {
println!("Please input your guess.");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
println!("You guessed: {}", guess);
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
Congrats, we have now successfully built a CLI game in Rust!
We now have a basic understanding of Rust syntax, error handling, and working with external libraries
Next, we’ll dive into deeper concepts like ownership, enums, and more!