1 00:00:06,570 --> 00:00:07,840 - In the previous section, 2 00:00:07,840 --> 00:00:10,190 we saw how to use an if statement in Rust, 3 00:00:10,190 --> 00:00:12,670 and now we're going to look at the match keyword. 4 00:00:12,670 --> 00:00:15,660 So, match is kind of similar to switch in other languages, 5 00:00:15,660 --> 00:00:17,010 but a bit more powerful maybe 6 00:00:17,010 --> 00:00:19,450 than what you've seen in those other languages. 7 00:00:19,450 --> 00:00:22,775 You can use match to test against integers, 8 00:00:22,775 --> 00:00:27,369 and Booleans, and enums. 9 00:00:27,369 --> 00:00:31,020 Imagine you had an enum for color, for example, red, green, 10 00:00:31,020 --> 00:00:32,339 or blue. 11 00:00:32,339 --> 00:00:33,740 You could have a match statement that says, you know, 12 00:00:33,740 --> 00:00:35,630 is it red? 13 00:00:35,630 --> 00:00:36,369 Is it green? 14 00:00:36,369 --> 00:00:37,319 Is it blue? 15 00:00:37,319 --> 00:00:39,420 So, a bit like a switch statement, but more powerful. 16 00:00:39,420 --> 00:00:42,400 You can also use match in Rust to match arrays, 17 00:00:43,360 --> 00:00:45,871 which is surprising, and tuples. 18 00:00:45,871 --> 00:00:47,969 A tuple we'll have a look at later. 19 00:00:47,969 --> 00:00:49,893 A tuple is kind of like an array, 20 00:00:49,893 --> 00:00:52,480 but where the element types can be different. 21 00:00:52,480 --> 00:00:54,239 So, a tuple could have like an integer, 22 00:00:54,239 --> 00:00:56,940 a string and a float for example. 23 00:00:56,940 --> 00:00:58,220 And also, structures. 24 00:00:58,220 --> 00:01:00,200 Structures are a bit like classes 25 00:01:00,200 --> 00:01:01,830 in object-oriented languages. 26 00:01:01,830 --> 00:01:05,880 So, you can use a match keyword to match any of these types. 27 00:01:05,880 --> 00:01:06,930 We'll have a look at all of these 28 00:01:06,930 --> 00:01:08,280 types later on in the course, 29 00:01:08,280 --> 00:01:10,129 but for now we'll just focus on integers 30 00:01:10,129 --> 00:01:12,460 because we just want to look at the basic syntax 31 00:01:12,460 --> 00:01:15,350 for match itself before we get carried away. 32 00:01:15,350 --> 00:01:16,830 So, here's the basic idea. 33 00:01:16,830 --> 00:01:19,190 I've got an integer, num, 34 00:01:19,190 --> 00:01:20,630 and then you see match 35 00:01:20,630 --> 00:01:23,280 and then you give it the value that you want to test on. 36 00:01:23,280 --> 00:01:25,130 So, I'm basically testing that's 37 00:01:25,130 --> 00:01:27,429 the expression that I'm testing, 38 00:01:27,429 --> 00:01:30,630 and then inside curly brackets you have each 39 00:01:30,630 --> 00:01:31,890 of the possible outcomes. 40 00:01:31,890 --> 00:01:35,580 It's like a switch case, but different syntax. 41 00:01:35,580 --> 00:01:37,690 In the case where the number is 100, 42 00:01:37,690 --> 00:01:39,210 then it will execute this code. 43 00:01:39,210 --> 00:01:41,070 The arrow is formal syntax. 44 00:01:42,240 --> 00:01:44,580 This is called an arm in Rust. 45 00:01:44,580 --> 00:01:47,080 In switch you'd call it a branch, 46 00:01:47,080 --> 00:01:51,040 but in Rust you call it an arm like in a crab, 47 00:01:51,040 --> 00:01:53,710 and then you have a comma between arms. 48 00:01:53,710 --> 00:01:55,730 Okay, so if the number was 100 49 00:01:55,730 --> 00:01:57,553 it would print 100. 50 00:01:57,553 --> 00:02:01,000 If the value of num was 200 it'll go in there. 51 00:02:01,000 --> 00:02:02,527 You have to have a catch all, 52 00:02:02,527 --> 00:02:05,760 the underscore catches any other value. 53 00:02:05,760 --> 00:02:08,340 So, if it was anything else it would come in here. 54 00:02:08,340 --> 00:02:10,880 Okay, so some points that I need to make. 55 00:02:10,880 --> 00:02:13,520 First of all, these branches are called arms. 56 00:02:13,520 --> 00:02:16,840 So, I should say this is one arm, that's another arm, 57 00:02:16,840 --> 00:02:19,040 that's another arm. 58 00:02:19,040 --> 00:02:21,589 You can enclose arms in curly brackets. 59 00:02:21,589 --> 00:02:25,260 If you have more than one statement to execute in an arm, 60 00:02:25,260 --> 00:02:28,280 then you have to group them together using curly brackets. 61 00:02:28,280 --> 00:02:29,770 So, I could do that. 62 00:02:29,770 --> 00:02:33,853 If the number was 100, I could say curly bracket, 63 00:02:34,990 --> 00:02:37,407 do some processing here ...., 64 00:02:38,730 --> 00:02:41,000 close curly bracket comma. 65 00:02:41,000 --> 00:02:44,710 So, you have a comma between the arms and curly brackets 66 00:02:44,710 --> 00:02:46,269 to group them together if you need to. 67 00:02:47,540 --> 00:02:49,680 The arms must be exhaustive, 68 00:02:49,680 --> 00:02:53,110 so Rust will complain if you don't cater 69 00:02:53,110 --> 00:02:54,420 for every possible value. 70 00:02:54,420 --> 00:02:55,770 When you declare a number, 71 00:02:55,770 --> 00:02:58,889 it could be any number between kind of minus 32,000 72 00:02:58,889 --> 00:03:00,469 and plus 32,000. 73 00:03:00,469 --> 00:03:03,440 So, if I didn't have this catch-all, 74 00:03:03,440 --> 00:03:05,200 the underscore at the end, 75 00:03:05,200 --> 00:03:07,750 I'd get an error from Rust 76 00:03:07,750 --> 00:03:12,559 because maybe the number wasn't captured by this arm, 77 00:03:12,559 --> 00:03:15,559 or that arm and it needs to do something 78 00:03:15,559 --> 00:03:16,879 in each match statement. 79 00:03:16,879 --> 00:03:20,380 Okay, so typically you will have a default. 80 00:03:20,380 --> 00:03:23,160 This is equivalent to default in other languages 81 00:03:23,160 --> 00:03:25,790 to make sure that you're catching all possible outcomes. 82 00:03:27,330 --> 00:03:31,345 Okay, so you can match ranges as well as individual numbers. 83 00:03:31,345 --> 00:03:34,609 So here I'm matching the number in a range, 84 00:03:34,609 --> 00:03:37,350 25.. equals 50. 85 00:03:37,350 --> 00:03:41,290 So, basically, from 25 up to and including 50. 86 00:03:41,290 --> 00:03:43,080 So, from a syntax point of view, 87 00:03:43,080 --> 00:03:46,300 it's two dots here, not three. 88 00:03:46,300 --> 00:03:48,170 You might have seen in other languages. 89 00:03:48,170 --> 00:03:50,880 And the upper limit, you have to use this syntax 90 00:03:50,880 --> 00:03:53,289 for the upper limit to be inclusive. 91 00:03:53,289 --> 00:03:56,030 Okay, the upper limit must be inclusive. 92 00:03:56,030 --> 00:03:58,110 It's a language limitation at the moment. 93 00:03:58,110 --> 00:04:01,990 So here, if the number was 25 through to 50, 94 00:04:01,990 --> 00:04:05,024 it would come into the first branch. 95 00:04:05,024 --> 00:04:07,520 If the number was 51 to 100, then it would come 96 00:04:07,520 --> 00:04:09,120 into the second branch. 97 00:04:09,120 --> 00:04:10,492 If it was anything else, 98 00:04:10,492 --> 00:04:12,490 then it goes into the default branch 99 00:04:12,490 --> 00:04:14,049 and it does that default processing. 100 00:04:15,370 --> 00:04:19,060 Okay, next up you can match multiple patterns. 101 00:04:19,060 --> 00:04:22,033 You can use the kind of like the pipe symbol 102 00:04:22,033 --> 00:04:25,250 to represent kind of like an or condition. 103 00:04:25,250 --> 00:04:27,689 So, I'm testing here if the number, 104 00:04:27,689 --> 00:04:32,689 if num is 25, or 50, or 75, 105 00:04:33,707 --> 00:04:37,000 then basically go into that first branch like so. 106 00:04:37,000 --> 00:04:41,340 On the other hand, if the number is 100, or 200, 107 00:04:41,340 --> 00:04:43,700 then go into this branch. 108 00:04:43,700 --> 00:04:45,429 And then if it's something else, 109 00:04:45,429 --> 00:04:48,379 then go into the default branch at the end. 110 00:04:48,379 --> 00:04:50,840 Okay, so that's quite a nice kind of technique. 111 00:04:50,840 --> 00:04:53,810 This is the equivalent concept of like a fall through 112 00:04:53,810 --> 00:04:55,620 in other languages, we'd say, 113 00:04:55,620 --> 00:05:00,620 switch the value 25 colon, case 50 colon, case 75 colon. 114 00:05:01,440 --> 00:05:03,050 This is how you achieve the same effect 115 00:05:03,050 --> 00:05:06,580 of fall through in Rust using the, 116 00:05:06,580 --> 00:05:09,219 it's like an OR operator, like a pipe symbol. 117 00:05:10,130 --> 00:05:12,140 You can also put conditions. 118 00:05:12,140 --> 00:05:14,690 You can have a matching condition at the end here. 119 00:05:14,690 --> 00:05:18,000 So, this is really starting to look quite powerful. 120 00:05:18,000 --> 00:05:20,990 I've taken the number and it kind of... 121 00:05:20,990 --> 00:05:22,519 what it will do is it'll put... 122 00:05:23,570 --> 00:05:27,450 it'll kind of copy the number into this variable, x, 123 00:05:27,450 --> 00:05:31,030 and then it has some kind of if statement, okay. 124 00:05:31,030 --> 00:05:34,980 So, copying the number into x, and then testing, 125 00:05:34,980 --> 00:05:36,440 is x less than 50? 126 00:05:37,280 --> 00:05:38,940 So basically, is the number less than 50? 127 00:05:40,270 --> 00:05:44,650 If it is, then this variable, you can use it over here. 128 00:05:45,620 --> 00:05:46,710 I could have actually used x. 129 00:05:46,710 --> 00:05:49,530 It kind of extracts the number into x 130 00:05:49,530 --> 00:05:51,160 and that variable then exists. 131 00:05:51,160 --> 00:05:53,460 You can use it here if you wanted to. 132 00:05:55,370 --> 00:05:58,029 And so that's the first condition. 133 00:05:58,029 --> 00:06:00,340 The second branch or the second arm, 134 00:06:00,340 --> 00:06:02,990 if the number is exactly equal to 75, 135 00:06:02,990 --> 00:06:05,370 then basically extract it into X, 136 00:06:05,370 --> 00:06:07,250 so I could use X in here, 137 00:06:07,250 --> 00:06:09,569 and then I've got a catch-all at the end. 138 00:06:09,569 --> 00:06:13,190 So, you can have if statements in your arms 139 00:06:13,190 --> 00:06:15,855 which is quite interesting. 140 00:06:15,855 --> 00:06:17,940 So, these are called match guards. 141 00:06:17,940 --> 00:06:22,480 It'll only match if the guard is satisfied. 142 00:06:25,490 --> 00:06:28,160 Right then, have a look at this example. 143 00:06:28,160 --> 00:06:31,400 Similar to what we had before, but in this example, 144 00:06:31,400 --> 00:06:36,400 basically I'm using match as an expression. 145 00:06:36,699 --> 00:06:39,680 So, it'll evaluate to be a single result. 146 00:06:39,680 --> 00:06:42,900 And the result of the whole thing is then assigned 147 00:06:42,900 --> 00:06:44,410 into that variable there. 148 00:06:44,410 --> 00:06:47,110 So, I can use match as an expression as opposed 149 00:06:47,110 --> 00:06:48,259 to just a statement, 150 00:06:48,259 --> 00:06:50,900 which is what I had in the previous examples. 151 00:06:50,900 --> 00:06:51,999 So, let's evaluate, 152 00:06:51,999 --> 00:06:54,049 and by the way you have to have a statement semicolon 153 00:06:54,049 --> 00:06:58,160 at the end to, you know, separate it from other statements. 154 00:06:58,160 --> 00:07:01,510 So, let's have a look at this expression to see 155 00:07:01,510 --> 00:07:03,630 which value it yields. 156 00:07:03,630 --> 00:07:05,890 So, it comes in, it checks the number, 157 00:07:06,809 --> 00:07:09,440 basically if the number is less than 50 158 00:07:09,440 --> 00:07:14,190 then in that case this is the outcome of the whole thing. 159 00:07:15,660 --> 00:07:19,050 The whole match expression will evaluate 160 00:07:19,050 --> 00:07:22,020 to be either the result of one arm, 161 00:07:22,020 --> 00:07:24,960 or another arm or another arm like that. 162 00:07:24,960 --> 00:07:28,209 Okay, so one of those three values will be the result 163 00:07:28,209 --> 00:07:30,810 of the whole thing either that value will be assigned 164 00:07:30,810 --> 00:07:31,643 into res, 165 00:07:32,524 --> 00:07:37,524 or this value 166 00:07:37,850 --> 00:07:40,552 will be assigned into res, 167 00:07:40,552 --> 00:07:45,325 or this value will be signed into res. 168 00:07:45,325 --> 00:07:48,940 Okay, so one of those three arms will be evaluated, 169 00:07:48,940 --> 00:07:52,123 and the value in that arm will be assigned 170 00:07:52,123 --> 00:07:53,170 into the variable, 171 00:07:53,170 --> 00:07:54,660 okay, which you can then output. 172 00:07:54,660 --> 00:07:58,059 So, the motivation for using an expression format 173 00:07:58,059 --> 00:07:59,639 is that you avoid duplication. 174 00:07:59,639 --> 00:08:00,950 All you're interested in is like 175 00:08:00,950 --> 00:08:03,700 getting out the value into res, 176 00:08:03,700 --> 00:08:06,211 and then you can use res here 177 00:08:06,211 --> 00:08:09,040 in one consistent statement afterwards. 178 00:08:09,040 --> 00:08:10,380 Okay, example time, 179 00:08:10,380 --> 00:08:13,510 so we'll go into the demo project lesson 3 flow control 180 00:08:13,510 --> 00:08:15,116 this time it's the demo match function 181 00:08:15,116 --> 00:08:16,546 we're gonna look at, 182 00:08:16,546 --> 00:08:19,370 so and then we'll run it obviously let's have a look. 183 00:08:19,370 --> 00:08:23,039 So, as before this is our lesson flow control. 184 00:08:23,039 --> 00:08:26,660 I'm gonna open that project in Visual Studio Code. 185 00:08:26,660 --> 00:08:30,050 Here we are and go into the main code. 186 00:08:30,050 --> 00:08:35,050 In my main function, I'm going to uncomment the demo match 187 00:08:35,400 --> 00:08:38,630 and here is the code for demo match. 188 00:08:39,650 --> 00:08:41,600 Kind of what we had in the PowerPoint slide, 189 00:08:41,600 --> 00:08:44,140 but I'm gonna do some experimentation just 190 00:08:44,140 --> 00:08:45,280 to show the kind of errors 191 00:08:45,280 --> 00:08:48,950 that you'll get if you don't do things exactly right. 192 00:08:48,950 --> 00:08:50,960 So, let's open up a terminal window, 193 00:08:50,960 --> 00:08:55,030 and I'll run the application in its current format. 194 00:08:55,030 --> 00:08:56,599 Everything should be good here. 195 00:08:56,599 --> 00:09:01,310 So, cargo run, just give that a while to finish. 196 00:09:01,310 --> 00:09:03,700 The usual warnings about unused functions 197 00:09:04,790 --> 00:09:06,480 and then the output. 198 00:09:06,480 --> 00:09:08,180 So first of all, num is 100. 199 00:09:09,030 --> 00:09:11,440 When it does the match here it'll come into 100 200 00:09:11,440 --> 00:09:15,339 and it prints 100, which is great, fantastic. 201 00:09:15,339 --> 00:09:17,939 And then it matches number is 100, 202 00:09:17,939 --> 00:09:21,210 so it's gonna come into this branch, this arm here, 203 00:09:21,210 --> 00:09:25,210 and it says 51 to 100, so that's good 51 to 100. 204 00:09:26,080 --> 00:09:30,099 And then moving on remember the number is 100, 205 00:09:30,099 --> 00:09:33,110 so when I have this kind of a multi-value match 206 00:09:33,110 --> 00:09:36,070 it's going to match in this case label here this arm 207 00:09:36,070 --> 00:09:37,680 is going to be executed, 208 00:09:37,680 --> 00:09:41,432 so it'll give me a 100 to 200 that's good, 209 00:09:41,432 --> 00:09:46,432 and then now, my number isn't less than 50, 210 00:09:46,754 --> 00:09:48,279 it's not 75, 211 00:09:48,279 --> 00:09:49,975 so it must be something else. 212 00:09:49,975 --> 00:09:51,570 So, it prints out something else. 213 00:09:51,570 --> 00:09:54,580 A little bit vague, but you get the drift. 214 00:09:54,580 --> 00:09:58,400 And then finally, this is my expression, res will be, 215 00:10:00,080 --> 00:10:03,490 each of these branches will be evaluated until it matches. 216 00:10:03,490 --> 00:10:06,589 And the result of each branch or arm, 217 00:10:06,589 --> 00:10:08,450 whichever arm it goes into, 218 00:10:08,450 --> 00:10:10,319 the result will be assigned into res. 219 00:10:11,580 --> 00:10:15,340 It's going to be this arm here, isn't it? 220 00:10:15,340 --> 00:10:17,500 It's not 50, it's not less than 50, 221 00:10:17,500 --> 00:10:20,400 it's not 75, it's something else. 222 00:10:20,400 --> 00:10:24,080 That string will be assigned into res, 223 00:10:24,080 --> 00:10:26,389 and then I can output the result of the magic expression 224 00:10:26,389 --> 00:10:30,350 is something else. 225 00:10:30,350 --> 00:10:32,569 Okay, so that all kind of worked as we expected. 226 00:10:33,610 --> 00:10:35,870 Let's see some errors. 227 00:10:35,870 --> 00:10:37,970 Let's see what happens, for example, 228 00:10:37,970 --> 00:10:41,470 if I accidentally forget to be exhaustive. 229 00:10:43,420 --> 00:10:47,403 Okay, so I'll reset my number to be 99, 230 00:10:47,403 --> 00:10:48,890 just to prove the point 231 00:10:48,890 --> 00:10:52,330 that it doesn't necessarily need to be 100 or 200. 232 00:10:52,330 --> 00:10:54,150 And let's see what happens 233 00:10:54,150 --> 00:10:57,320 when I have that first match statement. 234 00:10:57,320 --> 00:10:58,480 So, cargo run. 235 00:10:59,540 --> 00:11:02,540 Okay, I am getting an error on line, 236 00:11:04,430 --> 00:11:07,097 it's complaining about line 46. 237 00:11:07,940 --> 00:11:09,420 Yes, line 46. 238 00:11:11,000 --> 00:11:15,417 My number is an integer which can go from like, well, 239 00:11:16,610 --> 00:11:19,509 minus a big number to plus a big number, 240 00:11:19,509 --> 00:11:21,559 and it's saying the patterns that are specified, 241 00:11:21,559 --> 00:11:23,422 these are called patterns, 242 00:11:23,422 --> 00:11:26,100 it only caters for, it doesn't cater for, 243 00:11:26,100 --> 00:11:30,110 like minus the smallest number up to 99. 244 00:11:31,410 --> 00:11:32,490 The minimum value, 245 00:11:32,490 --> 00:11:35,722 it tells me that this is an I32 by the way, 246 00:11:35,722 --> 00:11:38,222 I32 has a constant called min. 247 00:11:39,130 --> 00:11:43,580 So, from the minimum value up to 99, 248 00:11:43,580 --> 00:11:48,530 and then from 101 up to 199 and then from 201 up 249 00:11:49,430 --> 00:11:52,639 to the maximum number for an i32. 250 00:11:52,639 --> 00:11:54,740 Basically, everything apart from 100 251 00:11:54,740 --> 00:11:59,270 and 200 are not catered for in my conditions. 252 00:11:59,270 --> 00:12:02,850 It's not exhaustive and it has to be exhaustive. 253 00:12:02,850 --> 00:12:07,250 So, I would need to add in the catch all here 254 00:12:07,250 --> 00:12:10,520 to make it exhaustive, okay. 255 00:12:10,520 --> 00:12:12,309 And then one other thing I'll just point out 256 00:12:12,309 --> 00:12:14,219 before we kind of close this demo. 257 00:12:14,219 --> 00:12:16,160 If you're doing a match condition, 258 00:12:16,160 --> 00:12:18,250 like a range I should say, 259 00:12:18,250 --> 00:12:20,960 the range here has to be inclusive. 260 00:12:20,960 --> 00:12:25,080 You've got to say, you know, up to and include in 50. 261 00:12:25,080 --> 00:12:28,330 If you leave off the equal sign, 262 00:12:28,330 --> 00:12:30,212 like you might be tempted to do, 263 00:12:30,212 --> 00:12:32,700 let me just make sure I've saved that file, 264 00:12:32,700 --> 00:12:35,289 then watch what happens now. 265 00:12:37,449 --> 00:12:41,680 It says I've got an error on line 53. 266 00:12:43,209 --> 00:12:46,670 Okay, so here, I've tried to have, 267 00:12:46,670 --> 00:12:49,130 what I've tried to do is have an exclusive upper bound 268 00:12:49,130 --> 00:12:52,990 I've tried to basically say 25 to 49 effectively, 269 00:12:52,990 --> 00:12:57,990 but it says this syntax here the exclusive range pattern 270 00:12:58,290 --> 00:13:01,000 is experimental in other words you're not allowed 271 00:13:01,000 --> 00:13:03,530 to have an exclusive pattern like up to, 272 00:13:03,530 --> 00:13:05,970 but not including. 273 00:13:05,970 --> 00:13:08,750 It has to be inclusive to include the upper limit like so. 274 00:13:09,719 --> 00:13:12,900 Okay, so if you really only wanted to include up to 49 275 00:13:12,900 --> 00:13:15,030 then you would have to write it that way. 276 00:13:15,030 --> 00:13:16,160 And if you really just wanted to include it up to, 277 00:13:16,160 --> 00:13:18,440 but not including 100, 278 00:13:18,440 --> 00:13:22,969 you'd have to write it that way up to including 99, 279 00:13:22,969 --> 00:13:24,080 and that would then give you the effect 280 00:13:24,080 --> 00:13:26,570 that you're looking for. 281 00:13:26,570 --> 00:13:28,500 Okay, so that's the match keyword. 282 00:13:28,500 --> 00:13:31,490 We've just been using match here with simple integers. 283 00:13:31,490 --> 00:13:34,540 All ready, you can kind of see that it's quite powerful 284 00:13:34,540 --> 00:13:38,410 with range matching and multiple values matching 285 00:13:38,410 --> 00:13:42,429 and having guards like an if statement as part 286 00:13:42,429 --> 00:13:45,240 of your condition and being able to evaluate match 287 00:13:45,240 --> 00:13:47,520 as an expression to assign to a variable. 288 00:13:47,520 --> 00:13:49,500 So, it's quite powerful already. 289 00:13:49,500 --> 00:13:51,690 What we'll do later in the course is have a look 290 00:13:51,690 --> 00:13:54,420 at how to use match with other types like enums, 291 00:13:54,420 --> 00:13:57,670 and arrays, and tuples, and structures.