@@ -956,6 +956,102 @@ Enums
956956
957957## Match
958958
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+
9591055## Looping
9601056
9611057for
0 commit comments