@@ -956,6 +956,102 @@ Enums
956
956
957
957
## Match
958
958
959
+ Often, a simple ` if ` /` else ` isn't enough, because you have more than two
960
+ possible options. And ` else ` conditions can get incredibly complicated. So
961
+ what's the solution?
962
+
963
+ Rust has a keyword, ` match ` , that allows you to replace complicated ` if ` /` else `
964
+ groupings with something more powerful. Check it out:
965
+
966
+ ``` rust
967
+ let x = 5i ;
968
+
969
+ match x {
970
+ 1 => println! (" one" ),
971
+ 2 => println! (" two" ),
972
+ 3 => println! (" three" ),
973
+ 4 => println! (" four" ),
974
+ 5 => println! (" five" ),
975
+ _ => println! (" something else" ),
976
+ }
977
+ ```
978
+
979
+ ` match ` takes an expression, and then branches based on its value. Each 'arm' of
980
+ the branch is of the form ` val => expression ` . When the value matches, that arm's
981
+ expression will be evaluated. It's called ` match ` because of the term 'pattern
982
+ matching,' which ` match ` is an implementation of.
983
+
984
+ So what's the big advantage here? Well, there are a few. First of all, ` match `
985
+ does 'exhaustiveness checking.' Do you see that last arm, the one with the
986
+ underscore (` _ ` )? If we remove that arm, Rust will give us an error:
987
+
988
+ ``` {ignore,notrust}
989
+ error: non-exhaustive patterns: `_` not covered
990
+ ```
991
+
992
+ In other words, Rust is trying to tell us we forgot a value. Because ` x ` is an
993
+ integer, Rust knows that it can have a number of different values. For example,
994
+ ` 6i ` . But without the ` _ ` , there is no arm that could match, and so Rust refuses
995
+ to compile. ` _ ` is sort of like a catch-all arm. If none of the other arms match,
996
+ the arm with ` _ ` will. And since we have this catch-all arm, we now have an arm
997
+ for every possible value of ` x ` , and so our program will now compile.
998
+
999
+ ` match ` statements also destructure enums, as well. Remember this code from the
1000
+ section on enums?
1001
+
1002
+ ``` {rust}
1003
+ let x = 5i;
1004
+ let y = 10i;
1005
+
1006
+ let ordering = x.cmp(&y);
1007
+
1008
+ if ordering == Less {
1009
+ println!("less");
1010
+ } else if ordering == Greater {
1011
+ println!("greater");
1012
+ } else if ordering == Equal {
1013
+ println!("equal");
1014
+ }
1015
+ ```
1016
+
1017
+ We can re-write this as a ` match ` :
1018
+
1019
+ ``` {rust}
1020
+ let x = 5i;
1021
+ let y = 10i;
1022
+
1023
+ match x.cmp(&y) {
1024
+ Less => println!("less"),
1025
+ Greater => println!("greater"),
1026
+ Equal => println!("equal"),
1027
+ }
1028
+ ```
1029
+
1030
+ This version has way less noise, and it also checks exhaustively to make sure
1031
+ that we have covered all possible variants of ` Ordering ` . With our ` if ` /` else `
1032
+ version, if we had forgotten the ` Greater ` case, for example, our program would
1033
+ have happily compiled. If we forget in the ` match ` , it will not. Rust helps us
1034
+ make sure to cover all of our bases.
1035
+
1036
+ ` match ` is also an expression, which means we can use it on the right hand side
1037
+ of a ` let ` binding. We could also implement the previous line like this:
1038
+
1039
+ ```
1040
+ let x = 5i;
1041
+ let y = 10i;
1042
+
1043
+ let result = match x.cmp(&y) {
1044
+ Less => "less",
1045
+ Greater => "greater",
1046
+ Equal => "equal",
1047
+ };
1048
+
1049
+ println!("{}", result);
1050
+ ```
1051
+
1052
+ In this case, it doesn't make a lot of sense, as we are just making a temporary
1053
+ string where we don't need to, but sometimes, it's a nice pattern.
1054
+
959
1055
## Looping
960
1056
961
1057
for
0 commit comments