Match!
Have you ever seen code like this?
#![allow(unused)] fn main() { let choice = 1; if choice == 1 { guess_game(); } else if choice == 2 { convert_units(); } else if choice == 3 { test_unwrap(); } else if choice == 4 { quit(); } }
Have you wondered if that could be written in a clearer way?
Then you’re in luck! Presenting the match
:
#![allow(unused)] fn main() { let choice = 1; match choice { 1 => guess_game(), 2 => convert_units(), 3 => test_unwrap(), 4 => quit(), _ => {}, } }
As you can see, match
has a beautiful syntax. Concise, yet powerful, that goes
to the point.
What match
does is exploring different options that a value can take. So, if
we do:
#![allow(unused)] fn main() { let choice: i64 = 1; match choice { // ... } }
It is going to consider what values choice
can take. Since it is an i64
, it
can take billions of different numbers, either positive or negative, and for
each one we can specify what to do in each case.
But it does have a catch, as match
requires us to consider all
possibilities. That is, we need to cover all possible numbers and specify an
action for it.
To avoid specifying all options one by one, we can have a default by using the
underscore _ => ...
:
#![allow(unused)] fn main() { let choice: i64 = 1; match choice { 1 => do_something(), _ => panic!("Invalid option!"), } }
It can understand ranges too:
#![allow(unused)] fn main() { let choice: i64 = 1; match choice { 1 => do_something(), 2..=10 => panic!("This option is not supported yet"), _ => panic!("Invalid option!"), } }
And it can understand enums too!
#![allow(unused)] fn main() { enum Choice { GuessGame, ConvertUnits, TestUnwrap, Quit, InvalidChoice, } let choice = Choice::GuessGame; match choice { Choice::GuessGame => guess_game(), Choice::ConvertUnits => convert_units(), Choice::TestUnwrap => test_unwrap(), Choice::Quit => quit(), Choice::InvalidChoice => {}, } }
And this is useful to handle errors:
#![allow(unused)] fn main() { let input_number = "12345"; // provided by user let res_number:Result<i64> = input_number.parse(); match res_number { Ok(number) => println!("your number is {}", number), Err(e) => println!("There was an error parsing your number: {:?}", e), } }
A bit more advanced usage could be:
#![allow(unused)] fn main() { let input_number = "12345"; // provided by user let number:i64 = match input_number.parse() { Ok(number) => number, Err(e) => { println!("There was an error parsing your number: {:?}", e); return; } }; println!("your number is {}", number); }