1 00:00:00,000 --> 00:00:07,200 [No Audio] 2 00:00:07,233 --> 00:00:09,900 In this tutorial, we will be looking at the 3 00:00:09,933 --> 00:00:12,300 concept of Ownership within the context of 4 00:00:12,301 --> 00:00:15,300 Functions. To make sure that the Ownership 5 00:00:15,333 --> 00:00:18,000 rules are fresh in our mind, I have put them 6 00:00:18,001 --> 00:00:20,000 in comments at the start of the program. 7 00:00:20,400 --> 00:00:23,200 Let's recall these these rules once more so 8 00:00:23,201 --> 00:00:26,033 that they become fresh again. The first rule 9 00:00:26,066 --> 00:00:28,100 is that, each value must have an owner. 10 00:00:28,300 --> 00:00:31,400 The second rule is that there is exactly one 11 00:00:31,401 --> 00:00:34,300 owner at any time and the last rule is that, 12 00:00:34,533 --> 00:00:36,133 when the owner goes out of scope, 13 00:00:36,134 --> 00:00:37,366 the value will be dropped. 14 00:00:38,700 --> 00:00:39,700 Let us recall the key 15 00:00:39,701 --> 00:00:42,100 concepts we learned. We looked at the 16 00:00:42,133 --> 00:00:44,200 differences between a move and a copy. 17 00:00:44,700 --> 00:00:47,300 The copy means making a new copy of the primitive 18 00:00:47,301 --> 00:00:50,200 variables in the stack, while a move occurs 19 00:00:50,233 --> 00:00:52,633 when a non-primitive value is being assigned 20 00:00:52,666 --> 00:00:55,900 to another variable. We also explain the 21 00:00:55,933 --> 00:00:58,733 concept of referencing, which is just a 22 00:00:58,766 --> 00:01:01,300 reference and is used to borrow some value 23 00:01:01,301 --> 00:01:04,733 without affecting the Ownership. Lastly, we 24 00:01:04,766 --> 00:01:07,200 looked at the scope, which is indicated in 25 00:01:07,233 --> 00:01:09,933 Rust by anything within curly brackets, which 26 00:01:09,966 --> 00:01:12,833 are also called code blocks or code segments. 27 00:01:14,100 --> 00:01:16,000 When the ending curly brackets are reached, 28 00:01:16,100 --> 00:01:18,333 the scope of the variable defined inside the 29 00:01:18,366 --> 00:01:20,933 code segment ends and it has been dropped. 30 00:01:21,033 --> 00:01:23,700 And if it resides inside the Heap, then its 31 00:01:23,733 --> 00:01:26,700 memory will be returned back to the operating system. 32 00:01:27,400 --> 00:01:30,100 Okay, this was just a refresher of 33 00:01:30,101 --> 00:01:32,500 the last two tutorials in this section. Now 34 00:01:32,533 --> 00:01:34,500 let us start with today's learning agenda, 35 00:01:34,501 --> 00:01:36,600 that is to learn how the Ownership works 36 00:01:36,601 --> 00:01:39,233 within the context of Functions. I will 37 00:01:39,266 --> 00:01:41,900 declare a few variables. The first variable 38 00:01:41,901 --> 00:01:46,600 called stack_num will have a value of let's say 32. 39 00:01:48,033 --> 00:01:49,033 The second variable 40 00:01:49,066 --> 00:01:50,933 called heap_num is a vector 41 00:01:50,966 --> 00:01:52,166 containing some values. 42 00:01:52,167 --> 00:01:57,800 [No Audio] 43 00:01:57,833 --> 00:02:00,000 The first variable in this case now, is a 44 00:02:00,001 --> 00:02:03,000 simple integer, which we know has fixed size 45 00:02:03,033 --> 00:02:05,300 and therefore will be stored inside the Stack. 46 00:02:05,400 --> 00:02:07,433 And the second variable is a vector, which is 47 00:02:07,466 --> 00:02:10,166 of variable size, and therefore it is going to 48 00:02:10,199 --> 00:02:13,833 be stored on the Heap. I intentionally named 49 00:02:13,866 --> 00:02:15,600 them like this to reflect where these 50 00:02:15,601 --> 00:02:17,800 variables will be stored inside the memory. 51 00:02:18,900 --> 00:02:20,666 Next, I will define a function called 52 00:02:20,667 --> 00:02:23,500 stack_function, which is going to accept 53 00:02:23,533 --> 00:02:26,100 the stack_num variable as input. 54 00:02:26,101 --> 00:02:31,700 [No Audio] 55 00:02:31,701 --> 00:02:35,000 Inside the function, we will update the value 56 00:02:35,001 --> 00:02:37,400 of the input. I will also display the contents 57 00:02:37,401 --> 00:02:39,100 of the variable inside the function. 58 00:02:39,101 --> 00:02:46,600 [No Audio] 59 00:02:46,601 --> 00:02:49,300 Inside the main I will call this function 60 00:02:49,301 --> 00:02:52,800 with the stack_num as its input. 61 00:02:52,801 --> 00:02:59,933 [No Audio] 62 00:02:59,966 --> 00:03:02,766 I will add so print, I will also add a print 63 00:03:02,767 --> 00:03:04,633 statement to indicate the current value of 64 00:03:04,666 --> 00:03:06,466 the variable stack_num. 65 00:03:06,467 --> 00:03:12,600 [No Audio] 66 00:03:12,601 --> 00:03:15,133 Now you may note that, the variable stack_num 67 00:03:15,633 --> 00:03:16,733 which is passed to the 68 00:03:16,766 --> 00:03:19,400 function is not mutable. However, inside the 69 00:03:19,401 --> 00:03:21,800 function definition of the stack_function, 70 00:03:21,801 --> 00:03:23,833 you may note that the variable var 71 00:03:24,000 --> 00:03:26,300 is considered to be mutable, and inside the 72 00:03:26,333 --> 00:03:29,100 function we are changing its value to a value of 56. 73 00:03:30,200 --> 00:03:32,200 So what happens basically is, when we 74 00:03:32,233 --> 00:03:34,200 pass a variable to a function which is 75 00:03:34,201 --> 00:03:37,466 stored on the Stack, that is variables of 76 00:03:37,500 --> 00:03:39,200 primitive types such as integers. 77 00:03:39,633 --> 00:03:42,200 So the function will make a copy of that and will 78 00:03:42,233 --> 00:03:45,200 use a copy. The move operation does not take 79 00:03:45,233 --> 00:03:47,500 place in this case. This means that the 80 00:03:47,501 --> 00:03:49,600 updation of the value inside the function 81 00:03:49,601 --> 00:03:51,433 does not affect the original value of the 82 00:03:51,466 --> 00:03:54,700 variable stack_num, and it will 83 00:03:54,733 --> 00:03:57,200 therefore remain unchanged in the main function. 84 00:03:57,700 --> 00:03:59,700 However, the variable stack_num 85 00:03:59,701 --> 00:04:01,500 is immutable, whil the 86 00:04:01,533 --> 00:04:04,200 variable var inside the function is declared 87 00:04:04,201 --> 00:04:08,333 to be mutable. We can do this as they are two 88 00:04:08,400 --> 00:04:11,000 different variables, since they are copies 89 00:04:11,033 --> 00:04:12,900 and represent different things now. 90 00:04:14,333 --> 00:04:16,700 Let us execute this to confirm the result. 91 00:04:16,701 --> 00:04:24,100 [No Audio] 92 00:04:24,101 --> 00:04:26,733 Please note that, even it does not matter if 93 00:04:26,766 --> 00:04:28,600 we use the same variable names in the main 94 00:04:28,633 --> 00:04:31,500 and inside the function. The essential 95 00:04:31,501 --> 00:04:33,900 behavior that we explained will remain the same. 96 00:04:34,233 --> 00:04:36,100 Let me change the variable name inside 97 00:04:36,101 --> 00:04:39,900 the function to, so that it exactly uses the 98 00:04:39,901 --> 00:04:42,500 same name as the variable inside the main function. 99 00:04:42,501 --> 00:04:48,900 [No Audio] 100 00:04:48,933 --> 00:04:51,700 In this case, still the variable stack_num 101 00:04:51,701 --> 00:04:53,200 defined inside the function 102 00:04:53,201 --> 00:04:56,233 will be a different variable from the stack_num 103 00:04:56,266 --> 00:04:57,900 defined inside the main function. 104 00:04:58,700 --> 00:05:00,733 Let us execute to confirm that the behavior 105 00:05:00,734 --> 00:05:03,300 of the program does not change due to this. 106 00:05:03,301 --> 00:05:10,600 [No Audio] 107 00:05:10,633 --> 00:05:12,600 The summary so far is that, when a variable 108 00:05:12,601 --> 00:05:14,900 which is on the stack is passed to a function, 109 00:05:14,901 --> 00:05:17,866 it is simply going to be copied and not moved. 110 00:05:19,633 --> 00:05:21,000 Now let us see what happens to a 111 00:05:21,001 --> 00:05:23,100 variable which is on a Heap is passed to a 112 00:05:23,101 --> 00:05:26,200 function. I will write a function outside the 113 00:05:26,233 --> 00:05:28,200 main which will use the variable on Heap, 114 00:05:28,500 --> 00:05:32,300 this function will accept the vector as an input. 115 00:05:32,333 --> 00:05:37,800 [No Audio] 116 00:05:37,801 --> 00:05:39,333 Inside the function, I will use the 117 00:05:39,366 --> 00:05:41,033 variable in a print statement and will 118 00:05:41,066 --> 00:05:42,666 display its contents. 119 00:05:42,667 --> 00:05:48,800 [No Audio] 120 00:05:48,801 --> 00:05:50,700 Let us call this function from the main. 121 00:05:50,701 --> 00:05:57,033 [No Audio] 122 00:05:57,066 --> 00:05:58,800 Next, let us print the variable. 123 00:05:58,801 --> 00:06:05,633 [No Audio] 124 00:06:05,634 --> 00:06:07,600 You may note that the compiler is complaining 125 00:06:07,633 --> 00:06:10,033 already. Let us see the error message to 126 00:06:10,034 --> 00:06:13,500 have some intuition. it says borrowed of a 127 00:06:13,501 --> 00:06:17,033 moved value. What happens basically is that, 128 00:06:17,066 --> 00:06:19,000 when a variable which is on the Heap is 129 00:06:19,033 --> 00:06:22,300 passed to a function, its value is moved to 130 00:06:22,333 --> 00:06:24,900 that of the function. In this case, the value 131 00:06:24,901 --> 00:06:26,933 of heap_num is being moved to the 132 00:06:26,966 --> 00:06:29,800 variable of var inside the heap_function. 133 00:06:30,900 --> 00:06:32,233 From the Ownership perspective, 134 00:06:32,266 --> 00:06:34,333 this means that the owner of the value is now 135 00:06:34,366 --> 00:06:36,733 changed, and the new owner is the variable 136 00:06:36,766 --> 00:06:39,400 var, which is inside the function. 137 00:06:40,033 --> 00:06:42,500 This variable resides inside the scope of this 138 00:06:42,501 --> 00:06:44,800 function. This means that when the function 139 00:06:44,801 --> 00:06:47,033 completes and finishes, the variable scope 140 00:06:47,066 --> 00:06:49,033 will end, and its value will be dropped. 141 00:06:50,033 --> 00:06:52,600 This is the third rule of ownership which says 142 00:06:52,601 --> 00:06:55,033 that, when the owner goes out of scope, 143 00:06:55,066 --> 00:06:57,066 the value will be dropped. So therefore, 144 00:06:57,133 --> 00:06:59,600 when the function is called and it 145 00:06:59,633 --> 00:07:01,800 completes its execution, so the variable 146 00:07:01,833 --> 00:07:04,433 here will no more exist, and therefore, using 147 00:07:04,466 --> 00:07:07,700 it afterwards will lead to errors. 148 00:07:08,733 --> 00:07:10,600 To summarize the discussion, when a variable 149 00:07:10,633 --> 00:07:13,100 on Stack is passed to a function, a copy occurs, 150 00:07:13,466 --> 00:07:15,266 while when a variable on Heap is 151 00:07:15,267 --> 00:07:17,466 passed to a function, a move occurs. 152 00:07:18,200 --> 00:07:21,466 Now if we intend to not lose the values, of our 153 00:07:21,467 --> 00:07:23,900 variables after the function ends, we can 154 00:07:23,933 --> 00:07:25,933 pass a reference to the variable instead of 155 00:07:25,966 --> 00:07:28,800 passing the value itself. This is also 156 00:07:28,833 --> 00:07:30,933 sometimes called as passing a value by 157 00:07:30,966 --> 00:07:35,000 reference, we can do this by putting an & 158 00:07:35,001 --> 00:07:37,300 before its name in the call to function. 159 00:07:38,333 --> 00:07:41,200 Moreover, we will also need to 160 00:07:41,201 --> 00:07:44,333 mention the appropriate syntax, that is, we 161 00:07:44,334 --> 00:07:47,200 need to put an & sign before the data type in 162 00:07:47,201 --> 00:07:48,700 the Function Parameter List. 163 00:07:48,701 --> 00:07:51,100 [No Audio] 164 00:07:51,133 --> 00:07:53,266 Using this syntax, the ownership will remain 165 00:07:53,267 --> 00:07:56,133 with the heap_num and it will not be transferred. 166 00:07:56,600 --> 00:07:58,200 Let us save this, and you may 167 00:07:58,201 --> 00:08:00,200 have already notice that, the compiler error 168 00:08:00,233 --> 00:08:02,200 message is gone and the compiler is no more 169 00:08:02,201 --> 00:08:05,700 complaining. If we want to change the value of 170 00:08:05,701 --> 00:08:07,733 the variable without changing the ownership, 171 00:08:07,900 --> 00:08:10,000 then in that case, we will be passing a 172 00:08:10,033 --> 00:08:12,300 mutable reference to the function. To pass a 173 00:08:12,301 --> 00:08:14,033 mutable reference to the function, we will 174 00:08:14,066 --> 00:08:17,000 write &mut instead of simple & in 175 00:08:17,001 --> 00:08:20,800 the function call. We will also indicate to 176 00:08:20,833 --> 00:08:22,500 the function that, you will be receiving a 177 00:08:22,501 --> 00:08:24,600 mutable reference by writing &mut 178 00:08:24,601 --> 00:08:30,066 before Vec. Let us update the 179 00:08:30,067 --> 00:08:32,100 variable inside the function by adding one 180 00:08:32,101 --> 00:08:34,966 more value to the vector, I will use the push 181 00:08:34,967 --> 00:08:37,200 function for this purpose, so I will write 182 00:08:37,201 --> 00:08:39,100 something like var.push 50. 183 00:08:39,101 --> 00:08:41,299 [No Audio] 184 00:08:41,300 --> 00:08:45,200 You may note, inside the main function that the compiler is 185 00:08:45,201 --> 00:08:47,366 not showing any error in the print statement, 186 00:08:47,367 --> 00:08:49,733 which means that the variable heap_num 187 00:08:49,734 --> 00:08:52,833 exists, and it is still the owner of the variable. 188 00:08:52,834 --> 00:08:55,200 [No Audio] 189 00:08:55,201 --> 00:08:56,700 In this case, both the print 190 00:08:56,701 --> 00:08:58,933 statements that is inside the function and 191 00:08:58,966 --> 00:09:01,500 inside the main function, will print the same 192 00:09:01,501 --> 00:09:03,800 vector because the vector has been updated 193 00:09:03,801 --> 00:09:05,600 inside the function without changing the 194 00:09:05,601 --> 00:09:07,000 ownership of the variable. 195 00:09:07,366 --> 00:09:09,033 Let us execute to see the output. 196 00:09:09,034 --> 00:09:16,000 [No Audio] 197 00:09:16,033 --> 00:09:17,833 You may note that, both the print statements 198 00:09:17,866 --> 00:09:20,900 are printing exactly the same vector. Okay, 199 00:09:20,901 --> 00:09:22,500 now it's time for a short quiz. 200 00:09:23,733 --> 00:09:26,700 I promise it will not be difficult, and I'm quite sure that 201 00:09:26,701 --> 00:09:28,933 you will guess the answer of this quiz correctly. 202 00:09:28,934 --> 00:09:31,933 [No Audio] 203 00:09:31,934 --> 00:09:34,300 I will first declare a vector called some_vec 204 00:09:34,333 --> 00:09:35,833 with some arbitrary values. 205 00:09:35,834 --> 00:09:41,800 [No Audio] 206 00:09:41,801 --> 00:09:43,800 Next, I will define another variable, and will 207 00:09:43,801 --> 00:09:46,200 assign to it this particular vector. 208 00:09:46,201 --> 00:09:51,533 [No Audio] 209 00:09:51,566 --> 00:09:55,700 Finally, I will add the statement of ref2 = &ref1. 210 00:09:55,733 --> 00:09:58,700 [No Audio] 211 00:09:58,701 --> 00:09:59,966 Now the quiz is to guess the 212 00:09:59,967 --> 00:10:02,333 owner of the vector in the first statement. 213 00:10:02,700 --> 00:10:04,133 I will give you 10 seconds to 214 00:10:04,166 --> 00:10:05,800 think, and then I will give you the answer. 215 00:10:05,801 --> 00:10:15,800 [No Audio] 216 00:10:15,801 --> 00:10:17,600 I believe you would have guessed the correct 217 00:10:17,633 --> 00:10:20,200 answer in this case, it is the ref1 218 00:10:20,201 --> 00:10:23,500 variable, let us see why this is so. The 219 00:10:23,533 --> 00:10:26,433 initial owner is the variable some_vec 220 00:10:26,466 --> 00:10:28,833 because we assigned to it the vector. 221 00:10:29,633 --> 00:10:31,900 The next statement changed the ownership, and 222 00:10:31,933 --> 00:10:34,500 now the new owner is the variable ref1. 223 00:10:35,100 --> 00:10:37,033 The last statement does not change the 224 00:10:37,066 --> 00:10:39,100 ownership, and therefore the ownership remains 225 00:10:39,133 --> 00:10:42,400 with the variable ref1. Okay, there are a 226 00:10:42,433 --> 00:10:44,800 couple of more small points that I want to 227 00:10:44,801 --> 00:10:46,733 clarify before we end this tutorial. 228 00:10:47,700 --> 00:10:50,066 The first point is related to a common mistake, 229 00:10:50,067 --> 00:10:53,166 junior level programmers in Rust tends to do, 230 00:10:53,600 --> 00:10:56,233 when they first encounter the ownership concept. 231 00:10:57,200 --> 00:10:58,566 The mistake is that they 232 00:10:58,567 --> 00:11:01,600 tend to create mutable variable, which is a 233 00:11:01,601 --> 00:11:04,000 reference to some other variable. The Rust 234 00:11:04,001 --> 00:11:06,533 don't allow you to create a mutable variable 235 00:11:06,566 --> 00:11:09,300 which is a reference. Let me clarify what I 236 00:11:09,301 --> 00:11:12,033 mean by this. Suppose I created a mutable 237 00:11:12,066 --> 00:11:14,533 variable vec_1 containing some values. 238 00:11:14,534 --> 00:11:19,600 [No Audio] 239 00:11:19,601 --> 00:11:21,133 In the next line, I want to create 240 00:11:21,166 --> 00:11:23,633 another variable which will hold a reference 241 00:11:23,666 --> 00:11:27,600 to the variable vec_1, but I declare it as mutable. 242 00:11:27,601 --> 00:11:32,533 [No Audio] 243 00:11:32,566 --> 00:11:34,000 Although this code will compile, 244 00:11:34,001 --> 00:11:36,500 but it does not make a strong sense. We 245 00:11:36,533 --> 00:11:38,833 should not be creating a reference which is 246 00:11:38,866 --> 00:11:42,100 itself mutable. Rather, we should be creating 247 00:11:42,101 --> 00:11:44,433 a mutable reference whose syntax is to put 248 00:11:44,466 --> 00:11:48,500 the word mut after the & sign. So you need 249 00:11:48,533 --> 00:11:50,533 to be aware of the correct syntax, and you 250 00:11:50,566 --> 00:11:52,400 should be able to differentiate between 251 00:11:52,700 --> 00:11:55,600 mutable reference and a reference being mutable. 252 00:11:56,233 --> 00:11:57,533 You might be thinking when would 253 00:11:57,566 --> 00:12:00,400 reference become handy, or when we would 254 00:12:00,401 --> 00:12:03,533 like to use them? This is a natural question, 255 00:12:03,600 --> 00:12:05,400 and it is supposed to come to your mind 256 00:12:05,433 --> 00:12:08,200 sooner or later. The references will become 257 00:12:08,201 --> 00:12:10,000 very handy in our programs when we are 258 00:12:10,001 --> 00:12:12,200 dealing with large amounts of data that are 259 00:12:12,233 --> 00:12:14,600 stored in some complicated data types such as 260 00:12:14,601 --> 00:12:17,233 structures. Of course, copying the whole data 261 00:12:17,266 --> 00:12:19,833 will not be effective and will be a costly 262 00:12:19,866 --> 00:12:22,100 operation to save time and resources of the 263 00:12:22,133 --> 00:12:25,366 computer system, we will be using a reference instead. 264 00:12:25,500 --> 00:12:27,333 Let us see an example of this to 265 00:12:27,334 --> 00:12:30,500 give you just an intuition. Suppose we have 266 00:12:30,533 --> 00:12:32,433 two strings in our programs containing some 267 00:12:32,466 --> 00:12:35,100 huge strings, I will create two string 268 00:12:35,101 --> 00:12:37,600 variables called large_data1 269 00:12:37,633 --> 00:12:39,800 and large_data2, and we'll initialize 270 00:12:39,833 --> 00:12:41,333 them from some string values. 271 00:12:41,334 --> 00:12:48,233 [No Audio] 272 00:12:48,234 --> 00:12:50,100 Let us assume for a minute, that these two 273 00:12:50,133 --> 00:12:52,433 variables are representing some large amounts 274 00:12:52,434 --> 00:12:54,533 of data that are being stored on the Heap. 275 00:12:55,800 --> 00:12:58,533 Now one of our program requirements is to 276 00:12:58,566 --> 00:13:00,633 merge these two strings together in a single 277 00:13:00,666 --> 00:13:04,000 variable. There can be two ways in which such 278 00:13:04,001 --> 00:13:07,000 a merge may occur, I will call it physical 279 00:13:07,033 --> 00:13:10,100 and conceptual. In physical type, we will be 280 00:13:10,133 --> 00:13:12,600 actually creating copies of these two large 281 00:13:12,601 --> 00:13:14,600 strings and then assigning a different 282 00:13:14,633 --> 00:13:17,533 variable name to it. This will involve heavy 283 00:13:17,566 --> 00:13:20,100 usage of memory and will not be cost effective. 284 00:13:20,833 --> 00:13:22,200 Another way which I will call 285 00:13:22,233 --> 00:13:25,133 conceptual, is to use references to these 286 00:13:25,166 --> 00:13:27,033 two variables and do not make copies. 287 00:13:27,533 --> 00:13:30,900 Let us see how this can be done. I will declare 288 00:13:30,933 --> 00:13:34,033 another variable for this purpose called huge_data. 289 00:13:34,034 --> 00:13:41,400 [No Audio] 290 00:13:41,401 --> 00:13:43,833 I can now easily initialize this from the 291 00:13:43,866 --> 00:13:46,600 references of the two large string values. 292 00:13:46,601 --> 00:13:52,900 [No Audio] 293 00:13:52,901 --> 00:13:55,200 This essentially provides a conceptual way of 294 00:13:55,233 --> 00:13:57,166 combining the two strings together without 295 00:13:57,167 --> 00:13:59,400 copying their contents again in the memory, 296 00:13:59,700 --> 00:14:01,300 but by rather using the references. 297 00:14:02,400 --> 00:14:05,000 This operation will work very fast, and will not 298 00:14:05,001 --> 00:14:07,800 have any significant overhead to work with them. 299 00:14:09,033 --> 00:14:11,700 Okay one last point before we end, 300 00:14:12,433 --> 00:14:14,933 this is with regards to the stack_function 301 00:14:14,966 --> 00:14:16,833 that we have created earlier. 302 00:14:17,400 --> 00:14:19,300 The function is having a local copy of the 303 00:14:19,333 --> 00:14:21,733 variable stack_num, which does not 304 00:14:21,766 --> 00:14:25,000 exist when the function end, and therefore its 305 00:14:25,001 --> 00:14:28,033 value is being lost. If we intend to use its 306 00:14:28,066 --> 00:14:30,900 value in the main function, and want its value 307 00:14:30,901 --> 00:14:33,133 to be returned back to the original variable, 308 00:14:33,400 --> 00:14:35,900 then we will make use of the return value 309 00:14:35,933 --> 00:14:38,533 from the function. We will define the function 310 00:14:38,566 --> 00:14:41,000 so that it returns a value, and in this case, 311 00:14:41,033 --> 00:14:42,900 the returning value will be assigned to the 312 00:14:42,933 --> 00:14:45,400 variable stack_num in the main function. 313 00:14:45,800 --> 00:14:47,333 Since we since we have already 314 00:14:47,366 --> 00:14:49,800 covered the definition of a function and its 315 00:14:49,801 --> 00:14:51,933 details, so I will keep it for the sake of 316 00:14:51,966 --> 00:14:54,633 the practice for you to see, how the 317 00:14:54,666 --> 00:14:57,000 return value may be stored inside a variable 318 00:14:57,001 --> 00:14:59,733 in the main. That brings us to the end of 319 00:14:59,766 --> 00:15:02,900 this tutorial, we have learned more concepts 320 00:15:02,933 --> 00:15:04,833 related to ownership and borrowing, but this 321 00:15:04,866 --> 00:15:06,800 time within the context of Functions. 322 00:15:07,600 --> 00:15:09,633 I hope you would have enjoyed this tutorial. 323 00:15:10,133 --> 00:15:12,800 We are having some practice problems at the end of 324 00:15:12,801 --> 00:15:14,900 this section of the course, I would strongly 325 00:15:14,901 --> 00:15:16,800 recommend that you go through them and try 326 00:15:16,801 --> 00:15:19,700 doing them immediately. If you delay doing 327 00:15:19,733 --> 00:15:22,400 them, then you may not be able to retain 328 00:15:22,433 --> 00:15:25,100 these concepts. If you do them right away, 329 00:15:25,101 --> 00:15:27,100 then these concepts will get mature in your 330 00:15:27,101 --> 00:15:29,933 mind, and will therefore remain in your mind 331 00:15:29,966 --> 00:15:31,500 for a longer period of time. 332 00:15:32,000 --> 00:15:33,700 See you again with more concepts regarding 333 00:15:33,701 --> 00:15:35,433 ownership, and until next tutorial, 334 00:15:35,434 --> 00:15:37,066 happy Rust programming. 335 00:15:37,067 --> 00:15:43,133 [No Audio]