@@ -1264,6 +1264,102 @@ do that with `match`.
12641264
12651265## Match
12661266
1267+ Often, a simple ` if ` /` else ` isn't enough, because you have more than two
1268+ possible options. And ` else ` conditions can get incredibly complicated. So
1269+ what's the solution?
1270+
1271+ Rust has a keyword, ` match ` , that allows you to replace complicated ` if ` /` else `
1272+ groupings with something more powerful. Check it out:
1273+
1274+ ``` rust
1275+ let x = 5i ;
1276+
1277+ match x {
1278+ 1 => println! (" one" ),
1279+ 2 => println! (" two" ),
1280+ 3 => println! (" three" ),
1281+ 4 => println! (" four" ),
1282+ 5 => println! (" five" ),
1283+ _ => println! (" something else" ),
1284+ }
1285+ ```
1286+
1287+ ` match ` takes an expression, and then branches based on its value. Each 'arm' of
1288+ the branch is of the form ` val => expression ` . When the value matches, that arm's
1289+ expression will be evaluated. It's called ` match ` because of the term 'pattern
1290+ matching,' which ` match ` is an implementation of.
1291+
1292+ So what's the big advantage here? Well, there are a few. First of all, ` match `
1293+ does 'exhaustiveness checking.' Do you see that last arm, the one with the
1294+ underscore (` _ ` )? If we remove that arm, Rust will give us an error:
1295+
1296+ ``` {ignore,notrust}
1297+ error: non-exhaustive patterns: `_` not covered
1298+ ```
1299+
1300+ In other words, Rust is trying to tell us we forgot a value. Because ` x ` is an
1301+ integer, Rust knows that it can have a number of different values. For example,
1302+ ` 6i ` . But without the ` _ ` , there is no arm that could match, and so Rust refuses
1303+ to compile. ` _ ` is sort of like a catch-all arm. If none of the other arms match,
1304+ the arm with ` _ ` will. And since we have this catch-all arm, we now have an arm
1305+ for every possible value of ` x ` , and so our program will now compile.
1306+
1307+ ` match ` statements also destructure enums, as well. Remember this code from the
1308+ section on enums?
1309+
1310+ ``` {rust}
1311+ let x = 5i;
1312+ let y = 10i;
1313+
1314+ let ordering = x.cmp(&y);
1315+
1316+ if ordering == Less {
1317+ println!("less");
1318+ } else if ordering == Greater {
1319+ println!("greater");
1320+ } else if ordering == Equal {
1321+ println!("equal");
1322+ }
1323+ ```
1324+
1325+ We can re-write this as a ` match ` :
1326+
1327+ ``` {rust}
1328+ let x = 5i;
1329+ let y = 10i;
1330+
1331+ match x.cmp(&y) {
1332+ Less => println!("less"),
1333+ Greater => println!("greater"),
1334+ Equal => println!("equal"),
1335+ }
1336+ ```
1337+
1338+ This version has way less noise, and it also checks exhaustively to make sure
1339+ that we have covered all possible variants of ` Ordering ` . With our ` if ` /` else `
1340+ version, if we had forgotten the ` Greater ` case, for example, our program would
1341+ have happily compiled. If we forget in the ` match ` , it will not. Rust helps us
1342+ make sure to cover all of our bases.
1343+
1344+ ` match ` is also an expression, which means we can use it on the right hand side
1345+ of a ` let ` binding. We could also implement the previous line like this:
1346+
1347+ ```
1348+ let x = 5i;
1349+ let y = 10i;
1350+
1351+ let result = match x.cmp(&y) {
1352+ Less => "less",
1353+ Greater => "greater",
1354+ Equal => "equal",
1355+ };
1356+
1357+ println!("{}", result);
1358+ ```
1359+
1360+ In this case, it doesn't make a lot of sense, as we are just making a temporary
1361+ string where we don't need to, but sometimes, it's a nice pattern.
1362+
12671363## Looping
12681364
12691365for
0 commit comments