Day 2
The content of this page and of the following ones is based on The Rust Book
1. Programming a guessing game
Let's first of all create a guessing_game
project:
cargo new guessing_game
cd guessing_game
Let's now modify src/main.rs
in such a way that it takes the user's guess:
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);
}
Let's break down this code:
- Rust has a prelude, i.e. a set of pre-defined items that every program can access. If the library we need to access is not standard, we can import it. There are a set of built-in libraries, such as
random
in python:std::io
is the library that makes you read/write from/to standard input - As always, we declare the
main
function (followed by()
and{}
) as the entrypoint of our script - We print some instructions
- We create a variable with
let
.let
is a declarative statement that binds a value to a variabele:
let apples = 5; // this is an immutable function
- The
apples
variable is immutable, meaning that once we give the variable a value, the value will not change. Theguess
variable we defined is mutable (keywordmut
): this variable is bound to a particular value, which is a type (String
) with its associated function (indicated by::
): thenew
function creates a new empty string. - We receive the user input with the
read_line
method associated toio::stdin()
. We pass the string&mut guess
as input. The&
sign means that this is a reference: references make pieces of code accessible to other pieces of code. References are safely and easily managed in Rust: they are immutable by default, so we need to pass&mut
and not only&guess
if we wanna maintain the mutability. io::stdin
returns aResult
, which is of a particular type: enumerations or enums. These type of data can be in one or multiple states: each of the possible states is a variant. In the case ofio::stdin
, the result tells us the status of the operation. If the operation was successful, we have "Ok" and the function returns the number of bytes passed by the user, if not we have "Err". The error tells us also what is broken in our code. We handle potential errors within the function by using theexpect
method. If theexpect
method catches an error, it wiill return the error code and explanation, if not, it will just return the number of bytes passed by the user. This is possible because allResult
instances have theexcept
method.
Note: this is different from error handling. With
expect
, the code crashes if there is an error, whereas with error handling this is not the case.