Today I’ll be tackling a topic I’ve been looking forward to. The Rust Match
construct. When I first saw match
, I didn’t really understand it at all. It felt like a foreign concept that would take forever to understand, but going through it is pretty understandable.
In the Rust Book, match
is introduced just after enum
as a way to conditionally handle each value in the enum
. I’ll follow the same approach because in JavaScript we do not support enums natively. I remember them from previous languages but it’s worth a refresher.
Enums
Enumerations are a data type that enables a variable to have a set of predefined constant values. The variable must have one of those values that have been defined for it.
Example:
You want to represent the cardinal points, North, East, West, and South in code. An enum would be a great data type for this. The code would look like below:
enum CardinalDirection {
North,
South,
East,
West
}
let direction = CardinalDirection::East;
Code language: JavaScript (javascript)
In Rust, you can add additional data to enums. The example given in the book would be Ip addresses.
enum IpAddrType {
V4,
V6
}
Let’s say you wanted to save the IP address itself, you could use a struct
but it’s more elegant to save that in the enum
variable.
enum IpAddrType {
V4(String),
V6(String)
}
Code language: JavaScript (javascript)
Here we’ve defined the options and say they accept a string. Our instance would be
let four = IpAddrType::V4(String::from("127.0.0.1"));
let six = IpAddrType::V6(String::from("::1"));
Code language: JavaScript (javascript)
Now that we have a basic understanding of enum
we can move on to what we are actually interested in. Match
Match
So I’m just going to start off with a statement that may be controversial.
Match
is a Rust Switch
statement.
Hold on, put the pitchforks down, even Rust acknowledges this… Great, now that the Rustician riots have been calmed slightly let me explain myself.
Match
is a Rust Switch
statement, but it’s not JUST a switch statement.
As a switch
Let’s do the normal stuff first to get a handle on the form. You can do everything you would normally use a switch for. So I can turn this JavaScript Switch into Match
switch(expression) {
case 1:
// do 1 stuff
break
case 2:
// do 2 stuff
break
default:
// default stuff
}
Code language: PHP (php)
In Rust this would be
match expression {
1 => //do 1 stuff,
2 => //do 2 stuff,
_ => //do default stuff
}
Code language: PHP (php)
More advanced Match
Match requires that the arms, be exhaustive, You will get a compiler error if they aren’t.
Like Switch, Match supports numbers
, strings
and bools
. Basically everything swtich can do. But on top of that Match also supports enums, ranges, structs, arrays, tupples, wildcards and placeholders. It will destructure variables if needed, so you can say
let tupple = (2, 2, 3);
match tupple {
(2, _, 3) => println!("#2_3"),
(_, _, 3) => println!("#__3"),
_ => println!("Default"),
}
Code language: PHP (php)
Or use enums
enum IpAddrType {
V4(String),
V6(String),
}
let ip = IpAddrType::V4(String::from("127.0.0.1"));
match ip {
IpAddrType::V6(ref ip_addr) => println!("match v6 {:?}", ip_addr),
IpAddrType::V4(ref ip_addr) => println!("match v4 {:?}", ip_addr),
}
Code language: PHP (php)
Essentially match has the form
match VALUE {
PATTERN => EXPRESSION,
PATTERN => EXPRESSION,
PATTERN => EXPRESSION,
}
Code language: PHP (php)
Where PATTERN is any valid Rust Pattern. On a side note this is the only time thus far I’ve seen the JavaScipt style anonymous thingy. Another example would be using ranges:
let i = 3;
match i {
1..=4 => println!("5 matched"),
5..=10 => println!("3 matched"),
_ => println!("other matched"),
}
Code language: PHP (php)
Note on Ranges, as of the time I wrote this, exclusive range pattern and open ended range patterns were still experimental. You can use them but not on stable.
If you want to use the value being matched, you can.
let i = 3;
match i {
value => println!("{} matched", value)
}
Code language: JavaScript (javascript)
Or a more complicated example:
let i = 5;
match i {
value if value > 4 => println!("{} matched", value),
value if value < 4 => println!("{} matched", value),
_ => println!("Other"),
}
Code language: PHP (php)
As you can see the possibilities are endless, so while match
is a switch
, it’s a way more powerful switch.
Realising it’s a switch goes a long way in understanding how to use it, at least it did for me. So what do you think? Did I do match justice? Are you still triggered I called it a switch? Let me know on Twitter, @phoexer and as always, happy coding.