1 00:00:00,000 --> 00:00:06,700 [No Audio] 2 00:00:06,701 --> 00:00:08,670 In this tutorial, we will be covering some 3 00:00:08,700 --> 00:00:10,950 additional topics with regards to closures. 4 00:00:11,400 --> 00:00:13,560 More specifically, we will be exploring some 5 00:00:13,561 --> 00:00:15,810 concepts related to closures and its 6 00:00:15,811 --> 00:00:18,150 capturing environment. So let's get started. 7 00:00:18,690 --> 00:00:20,850 Let us first refresh the contents from the 8 00:00:20,851 --> 00:00:23,250 last tutorial. In the previous tutorial, we 9 00:00:23,251 --> 00:00:25,530 looked at different syntaxes for defining the 10 00:00:25,531 --> 00:00:27,780 closures, let me quickly look at some of 11 00:00:27,781 --> 00:00:31,050 these. The first syntax was to explicitly 12 00:00:31,051 --> 00:00:32,766 define the inputs and outputs. 13 00:00:32,767 --> 00:00:38,160 [No Audio] 14 00:00:38,161 --> 00:00:41,070 The second syntax is to skip the types of 15 00:00:41,071 --> 00:00:42,496 the inputs and outputs. 16 00:00:42,497 --> 00:00:47,515 [No Audio] 17 00:00:47,516 --> 00:00:48,360 The types will be 18 00:00:48,361 --> 00:00:50,400 inferred in this case, when the closure is 19 00:00:50,401 --> 00:00:52,470 called for the first time in the program, and 20 00:00:52,471 --> 00:00:55,170 if the compiler is unable to infer, then it 21 00:00:55,171 --> 00:00:59,280 will complain. The third syntax was, when we 22 00:00:59,281 --> 00:01:02,010 have only a single statement in the body of the closure. 23 00:01:02,011 --> 00:01:07,890 [No Audio] 24 00:01:07,891 --> 00:01:09,780 In this case, we do not add the curly 25 00:01:09,781 --> 00:01:12,120 brackets. These three are basically three 26 00:01:12,121 --> 00:01:14,310 different styles in which we may define the 27 00:01:14,311 --> 00:01:16,860 closures. Please note that the compiler is 28 00:01:16,861 --> 00:01:20,200 complaining for the some_closure_2, 29 00:01:20,201 --> 00:01:21,660 and this will be resolved, when 30 00:01:21,661 --> 00:01:23,670 we use the closure for the first time inside 31 00:01:23,671 --> 00:01:25,710 the program with some suitable inputs, because 32 00:01:25,711 --> 00:01:27,900 the compiler is unable to currently deduce 33 00:01:27,901 --> 00:01:30,540 the inputs and output types. Okay, that was a 34 00:01:30,541 --> 00:01:32,370 quick recap, and now we will cover the main 35 00:01:32,371 --> 00:01:34,380 topic of this tutorial, which is related to 36 00:01:34,381 --> 00:01:36,666 closures and it's capturing environment. 37 00:01:37,733 --> 00:01:39,900 We will first look at the case, when the closure 38 00:01:39,930 --> 00:01:42,540 uses an immutable reference to a variable 39 00:01:42,541 --> 00:01:45,270 inside the code. I will declare a mutable 40 00:01:45,271 --> 00:01:48,000 vector with some values. Next, I will define 41 00:01:48,001 --> 00:01:50,250 a closure, and we'll use this vector inside 42 00:01:50,251 --> 00:01:51,869 the closure in a print statement. 43 00:01:51,870 --> 00:01:58,200 [No Audio] 44 00:01:58,201 --> 00:02:00,180 Let us now try to access the same vector 45 00:02:00,181 --> 00:02:02,037 outside the closure in a print statement. 46 00:02:02,038 --> 00:02:07,980 [No Audio] 47 00:02:07,981 --> 00:02:09,791 Finally, I will invoke the closure. 48 00:02:09,792 --> 00:02:14,850 [No Audio] 49 00:02:14,857 --> 00:02:17,100 Let us now understand what happened in this case. 50 00:02:17,300 --> 00:02:19,290 The first thing to note is that, we do 51 00:02:19,291 --> 00:02:21,630 not have mentioned the input to this closure. 52 00:02:21,750 --> 00:02:23,940 However, since the closure captures its 53 00:02:23,970 --> 00:02:25,830 environment, so all the variables which are 54 00:02:25,831 --> 00:02:28,110 currently in scope will be available inside 55 00:02:28,111 --> 00:02:30,750 the closure also. Moreover, in this case the 56 00:02:30,751 --> 00:02:33,060 Rust compiler will also decide how to use the 57 00:02:33,061 --> 00:02:36,030 variable inside the closure, as it is not 58 00:02:36,031 --> 00:02:38,430 being specified in the inputs and outputs of 59 00:02:38,431 --> 00:02:41,490 the closure. This means that the Rust 60 00:02:41,491 --> 00:02:44,070 compiler will be engaged in some inference, 61 00:02:44,430 --> 00:02:47,040 since the value is not being updated inside 62 00:02:47,041 --> 00:02:48,930 the closure. So by default, the Rust compiler 63 00:02:48,931 --> 00:02:50,730 will assume that, the value will be used 64 00:02:50,731 --> 00:02:53,400 inside the closure as an immutable reference, 65 00:02:53,430 --> 00:02:56,310 and therefore it will not change. Since the 66 00:02:56,311 --> 00:02:59,400 value inside the closure is being used as an 67 00:02:59,401 --> 00:03:01,633 immutable reference, therefore vec_1 68 00:03:01,634 --> 00:03:03,840 is available for us, as it is 69 00:03:03,841 --> 00:03:06,780 being used by reference. Remember the Rust 70 00:03:06,781 --> 00:03:08,670 ownership rules, according to which multiple 71 00:03:08,671 --> 00:03:10,740 readings of the values of variables or 72 00:03:10,741 --> 00:03:13,200 reference to the value of variables are okay, 73 00:03:13,230 --> 00:03:15,390 and does not create any issues. Therefore, 74 00:03:15,391 --> 00:03:17,160 the print statement outside the body of the 75 00:03:17,161 --> 00:03:20,460 closure is not creating any issues. Now if I 76 00:03:20,461 --> 00:03:23,130 add a statement of, let's say vec and then 77 00:03:23,160 --> 00:03:25,710 within the [1] = 15, 78 00:03:26,130 --> 00:03:28,530 the Rust compiler will rightfully complain. 79 00:03:28,740 --> 00:03:30,720 This is because, the vector is being borrowed 80 00:03:30,750 --> 00:03:33,390 is immutable and we cannot mutate or change 81 00:03:33,391 --> 00:03:35,910 its value, until the immutable reference goes 82 00:03:35,911 --> 00:03:38,820 out of scope. Once the some_closure 83 00:03:38,821 --> 00:03:41,070 is done, then the immutable reference will be 84 00:03:41,071 --> 00:03:43,320 out of scope. And then we may update its 85 00:03:43,321 --> 00:03:47,066 value. If I get the statement of vec_1 = 15 86 00:03:47,067 --> 00:03:49,170 from here and paste it after the 87 00:03:49,171 --> 00:03:51,240 statement of some_closure, so the 88 00:03:51,241 --> 00:03:53,033 compiler will have no issues. 89 00:03:53,933 --> 00:03:57,060 Okay, here is a small point to note the closure as pointed 90 00:03:57,061 --> 00:03:58,950 out in the previous tutorial are a bit 91 00:03:58,951 --> 00:04:01,200 different from a that of typical functions. 92 00:04:01,470 --> 00:04:03,510 Typical functions will only get a chance of 93 00:04:03,511 --> 00:04:05,370 being executed when they are being called 94 00:04:05,371 --> 00:04:07,200 from the main function or some other 95 00:04:07,201 --> 00:04:09,930 function. However, as soon as we declare the 96 00:04:09,931 --> 00:04:12,900 closure and assign it to some variable, so 97 00:04:12,901 --> 00:04:14,490 since the variable is in scope, the 98 00:04:14,491 --> 00:04:16,620 definition of the closure which is tied to 99 00:04:16,621 --> 00:04:19,470 the variable is also in some sense in scope. 100 00:04:19,800 --> 00:04:21,600 As a result you may note that, although we 101 00:04:21,601 --> 00:04:23,670 are calling the closure on this line, the 102 00:04:23,671 --> 00:04:25,920 vector of vec_1 is still being 103 00:04:25,921 --> 00:04:27,990 considered to be borrowed until the line, 104 00:04:28,020 --> 00:04:30,866 where we are calling the closure of some_closure. 105 00:04:31,066 --> 00:04:33,333 After the call is completed the immutable 106 00:04:33,334 --> 00:04:35,220 reference ends. This 107 00:04:35,221 --> 00:04:37,920 is why we can then modify or update the value 108 00:04:37,921 --> 00:04:40,350 of vec_1. Okay, now let us see 109 00:04:40,351 --> 00:04:42,390 what happens when a closure uses a mutable 110 00:04:42,391 --> 00:04:44,760 reference to some variable. I will change 111 00:04:44,761 --> 00:04:46,860 the statement inside the closure, so I will 112 00:04:46,861 --> 00:04:48,810 delete the statement and will push a value 113 00:04:48,811 --> 00:04:50,353 of 35 to the vector. 114 00:04:50,354 --> 00:04:54,646 [No Audio] 115 00:04:54,647 --> 00:04:55,770 Outside the closure I 116 00:04:55,771 --> 00:04:58,260 will keep the statement where I am calling 117 00:04:58,261 --> 00:05:00,000 the closure and will delete the rest of the 118 00:05:00,001 --> 00:05:03,570 statements. In this case now the closure is 119 00:05:03,571 --> 00:05:05,760 modifying the variable. So, the Rust compiler 120 00:05:05,761 --> 00:05:08,520 will infer, that the variable will be borrowed 121 00:05:08,521 --> 00:05:11,280 by the closure is a mutable reference, since 122 00:05:11,281 --> 00:05:13,530 it is a mutable reference. So therefore, an 123 00:05:13,531 --> 00:05:15,660 immutable reference to the same variable that 124 00:05:15,661 --> 00:05:17,670 is vec_1 will not be allowed until the 125 00:05:17,671 --> 00:05:19,530 variable of some_closure is in 126 00:05:19,531 --> 00:05:23,000 scope. Moreover, the variable of some_closure 127 00:05:23,001 --> 00:05:24,390 will be in scope until it 128 00:05:24,391 --> 00:05:27,150 is used for the last time. Moreover, please 129 00:05:27,180 --> 00:05:29,550 also note that we need to write the mut 130 00:05:29,551 --> 00:05:32,066 keyword before the variable of some_closure 131 00:05:32,067 --> 00:05:33,480 because in this case, the 132 00:05:33,481 --> 00:05:35,700 closure it is representing we'll be updating 133 00:05:35,701 --> 00:05:37,920 the value of some variable and therefore it 134 00:05:37,921 --> 00:05:40,500 needs to be mutable. So let me write mut 135 00:05:40,501 --> 00:05:42,833 before the name of the variable some_closure. 136 00:05:44,333 --> 00:05:46,170 Okay, what will happen if 137 00:05:46,200 --> 00:05:48,240 I add a print statement before the call to 138 00:05:48,241 --> 00:05:50,182 the closure, I will add the statement. 139 00:05:50,183 --> 00:05:54,000 [No Audio] 140 00:05:54,022 --> 00:05:55,942 And now, I will give you 10 seconds to think 141 00:05:55,943 --> 00:05:57,204 about the possible answer. 142 00:05:57,205 --> 00:06:07,439 [No Audio] 143 00:06:07,440 --> 00:06:09,179 I believe you would have guessed the correct 144 00:06:09,180 --> 00:06:11,489 answer, it is not allowed because it is being 145 00:06:11,490 --> 00:06:14,279 borrowed as mutable, since accessing the value 146 00:06:14,280 --> 00:06:16,169 is not allowed when a variable is being 147 00:06:16,170 --> 00:06:17,999 borrowed as mutable therefore, the Rust 148 00:06:18,000 --> 00:06:20,789 compiler will complain once the updation is 149 00:06:20,790 --> 00:06:23,309 done then we may proceed with using the value 150 00:06:23,729 --> 00:06:26,399 Okay now, I will take another short quiz, I 151 00:06:26,400 --> 00:06:28,529 will comment out this statement and now I 152 00:06:28,530 --> 00:06:30,973 will try to update the value of vec_1. 153 00:06:30,974 --> 00:06:34,933 [No Audio] 154 00:06:34,934 --> 00:06:37,649 This is also not allowed, but I want 155 00:06:37,650 --> 00:06:39,269 you to tell me the answer. I will give you 156 00:06:39,270 --> 00:06:40,532 again 10 seconds to think. 157 00:06:40,533 --> 00:06:49,980 [No Audio] 158 00:06:49,981 --> 00:06:51,720 I believe you would have guessed the answer. 159 00:06:51,960 --> 00:06:53,880 This is because multiple updations to the 160 00:06:53,881 --> 00:06:55,980 same variable are not allowed. In other 161 00:06:55,981 --> 00:06:58,890 words, we cannot borrow as immutable twice. 162 00:06:59,092 --> 00:07:01,522 This is against the Rust ownership rules. 163 00:07:01,950 --> 00:07:03,930 According to the ownership rules, we can only 164 00:07:03,931 --> 00:07:05,947 have a single immutable reference. 165 00:07:05,948 --> 00:07:08,755 In summary, in this case not only the immutable 166 00:07:08,756 --> 00:07:11,516 but multiple references are also not allowed 167 00:07:11,517 --> 00:07:14,600 when a variable is being used as a closure, unless 168 00:07:14,640 --> 00:07:16,950 we are done with the call to the closure and 169 00:07:16,951 --> 00:07:18,720 the variable representing the closure is 170 00:07:18,721 --> 00:07:21,420 no more in scope. We are however free to do, 171 00:07:21,450 --> 00:07:23,700 whatever we want to do with the vector once 172 00:07:23,701 --> 00:07:26,520 the call is done. That is after the line of 173 00:07:26,521 --> 00:07:28,650 some_closure. This is because the 174 00:07:28,651 --> 00:07:30,540 variable of some_closure is being 175 00:07:30,541 --> 00:07:33,166 dropped after the line in which we call the closure. 176 00:07:33,766 --> 00:07:35,220 We will cover the final topic of 177 00:07:35,221 --> 00:07:37,440 this tutorial. Now, we will be looking at a 178 00:07:37,441 --> 00:07:39,780 case when a value is being moved inside a 179 00:07:39,781 --> 00:07:42,870 closure. I will remove the statement inside 180 00:07:42,871 --> 00:07:45,840 the closure body, I will also keep only the 181 00:07:45,841 --> 00:07:48,060 line containing the call to the closure and 182 00:07:48,061 --> 00:07:50,440 with remove all other lines. 183 00:07:50,441 --> 00:07:54,200 [No Audio] 184 00:07:54,210 --> 00:07:55,890 Inside the body of the closure, I will 185 00:07:55,891 --> 00:07:58,140 declare another vec which will be 186 00:07:58,141 --> 00:08:00,299 initialized from the value of vec_1. 187 00:08:00,300 --> 00:08:02,566 [No Audio] 188 00:08:02,567 --> 00:08:04,260 Outside the body of the closure, I will 189 00:08:04,334 --> 00:08:06,810 add a couple of print statements after the 190 00:08:06,811 --> 00:08:08,366 call to the closure. 191 00:08:08,376 --> 00:08:12,700 [No Audio] 192 00:08:12,701 --> 00:08:15,600 Before explaining the issue in this print statement, 193 00:08:15,900 --> 00:08:18,180 we will first explain what happens inside the 194 00:08:18,181 --> 00:08:20,610 closure. The Rust compiler will try again to 195 00:08:20,611 --> 00:08:24,030 infer, how to use the value of the variable 196 00:08:24,031 --> 00:08:26,340 vec_1 since the line of code 197 00:08:26,341 --> 00:08:28,830 is actually moving its value and transferring 198 00:08:28,831 --> 00:08:32,066 the ownership from from vec_1 to that of vec_2. 199 00:08:32,133 --> 00:08:33,840 Therefore the Rust compiler will use 200 00:08:33,841 --> 00:08:36,510 the original values and not as a reference. 201 00:08:36,720 --> 00:08:38,760 Since the ownership has been transferred 202 00:08:38,761 --> 00:08:41,765 inside the closure, therefore the use of vec_1 203 00:08:41,766 --> 00:08:43,140 inside the print statement is 204 00:08:43,141 --> 00:08:46,133 not valid because the variable vec_1 205 00:08:46,134 --> 00:08:48,120 is no more in scope and has 206 00:08:48,121 --> 00:08:51,900 lost the ownership. Moreover the value of vec_2 207 00:08:51,901 --> 00:08:53,700 is also dropped since its 208 00:08:53,701 --> 00:08:55,920 scope was limited to the body of the closure 209 00:08:55,921 --> 00:08:57,990 so therefore the use of vec_2 inside the 210 00:08:57,991 --> 00:09:00,810 print statement is not valid. Okay with this 211 00:09:00,811 --> 00:09:02,700 we in this tutorial, we have looked at three 212 00:09:02,701 --> 00:09:05,280 scenarios in which the value of a variable 213 00:09:05,281 --> 00:09:07,920 may be used inside the closure. That is by 214 00:09:07,921 --> 00:09:10,770 immutable reference, by mutable reference, and 215 00:09:10,771 --> 00:09:13,680 by actual value. This specific case on how to 216 00:09:13,681 --> 00:09:16,080 use the values are inferred by the Rust 217 00:09:16,081 --> 00:09:17,850 compiler depending on how the closure 218 00:09:17,851 --> 00:09:20,700 operates on the values. Do come back again for 219 00:09:20,701 --> 00:09:23,445 learning more and until then happy Rust programming. 220 00:09:23,446 --> 00:09:27,833 [No Audio]