I just started learning Rust and I often have some questions that I can't find any answer. I don't really know how and where to post my question, so I'll try SO.
I started to read the Rust documentation on the website and I did the Guessing game example.
I realized that the match cmp
expression inside the loop could be turned into a statement and everything still works. So I wonder why and what version should really be preferred?
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1, 101);
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;
}
} // <=== here should it be ended as statement (;) or not?
}
}
match
, if
, loop
, and other expressions that have {}
blocks are treated specially by the Rust compiler. When these expressions occur as expression statements, that is, not as part of a larger expression, and the type of the expression that has the block is ()
, you do not have to put ;
after it to separate it from a following statement.
This is not the case for expression statements without blocks, which always must be separated from the following statement (if one exists) by ;
, even if their type is ()
.
Because this rule exists, it is usual in Rust not to put ;
after match
, if
, unsafe
, etc. when they are used only for side effects, or after for
and while
loops (which are always used only for side effects, since they always return ()
).
That said, both rustfmt and Clippy seem to be fine with the extra ;
, so if you prefer it there for aesthetic reasons, you're unlikely to offend anyone by using it.
In Rust, loop blocks expect a "return" type of the empty type ()
. This is the type that's returned when you end with a statement and don't return anything at all (e.g. {f();}
). println!
returns the empty type, so the code you posted works either way, however I would say it makes more sense to end it with a semicolon.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With