@@ -1264,6 +1264,102 @@ do that with `match`.
1264
1264
1265
1265
## Match
1266
1266
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
+
1267
1363
## Looping
1268
1364
1269
1365
for
0 commit comments