1 00:00:00,520 --> 00:00:04,930 In this lecture, we are going to discuss a core concept called ownership. 2 00:00:05,260 --> 00:00:09,610 I consider Rust's to be a reliable language for its memory safety. 3 00:00:09,850 --> 00:00:14,530 We've talked about memory before, but how does rust achieve memory safety? 4 00:00:14,830 --> 00:00:17,200 That's what I want to talk about in this lecture. 5 00:00:17,410 --> 00:00:23,500 We should take the time to understand the underlying features that make rust a memory safe language. 6 00:00:24,040 --> 00:00:27,880 One of the biggest problems in the programming world is memory leaks. 7 00:00:28,090 --> 00:00:30,310 They are a plague to most programmers. 8 00:00:30,610 --> 00:00:34,930 A memory leak is when a program fails to keep track of its data properly. 9 00:00:35,260 --> 00:00:41,740 Let's say we had a variable for storing a number of variables take up memory on the user's machine at 10 00:00:41,740 --> 00:00:42,430 some point. 11 00:00:42,580 --> 00:00:47,500 We're not going to need the variable anymore if we forget to release memory. 12 00:00:47,530 --> 00:00:54,820 We've created a memory leak instead of reusing memory programs will need to reserve additional memory 13 00:00:54,820 --> 00:00:58,240 for additional resources in some languages. 14 00:00:58,390 --> 00:01:02,230 We need to reform the operation of allocating the memory. 15 00:01:02,560 --> 00:01:09,790 However, Ruskin clean memory for us, we don't need to write additional code to benefit from this feature. 16 00:01:10,390 --> 00:01:15,190 This behavior makes rust highly popular among system programmers. 17 00:01:15,460 --> 00:01:18,820 It emphasizes cleaning memory under the hood. 18 00:01:19,090 --> 00:01:21,550 Rust utilizes an ownership model. 19 00:01:21,940 --> 00:01:25,600 Values assigned to a variable are owned by that variable. 20 00:01:25,900 --> 00:01:27,430 It is as simple as that. 21 00:01:27,670 --> 00:01:31,630 Whenever we create a variable, we are creating a new owner. 22 00:01:32,320 --> 00:01:37,720 Rust will automatically allocate memory when a variable is not needed anymore. 23 00:01:37,960 --> 00:01:42,880 In rust lingo, you may hear this process referred to as dropping a value. 24 00:01:43,240 --> 00:01:47,440 This behavior does carry some consequences we should be aware of. 25 00:01:47,770 --> 00:01:51,190 Let's take a look at an example of ownership gone wrong. 26 00:01:52,670 --> 00:01:57,110 We are going to continue working on the same project from the previous lecture. 27 00:01:57,380 --> 00:02:00,020 We have a variable called my account. 28 00:02:00,410 --> 00:02:03,440 This variable has ownership of the value. 29 00:02:03,860 --> 00:02:06,890 The question is when does the value get dropped? 30 00:02:07,220 --> 00:02:10,370 Values are dropped when the function is finished running. 31 00:02:10,940 --> 00:02:17,450 In this example, the main function is to automatically call whenever we run the program once the main 32 00:02:17,450 --> 00:02:19,010 function is finished running. 33 00:02:19,190 --> 00:02:23,570 Russ will release the memory from the variables defined inside of it. 34 00:02:23,870 --> 00:02:27,860 We don't need to make further changes to benefit from this behavior. 35 00:02:28,520 --> 00:02:33,230 Let's say we want to outsource the print line macros into different functions. 36 00:02:33,500 --> 00:02:41,150 We will define two functions for printing the balance and verified fields above the main function define 37 00:02:41,150 --> 00:02:43,370 a function called print balance. 38 00:02:45,920 --> 00:02:52,340 Inside the argument list, let's set an argument called accounts with the type set to bank accounts. 39 00:02:54,930 --> 00:03:01,950 Next, inside the function, we're going to print the balance field, the values inside this macro will 40 00:03:01,950 --> 00:03:05,460 be similar to the print line macro, any main function. 41 00:03:09,690 --> 00:03:12,570 Lastly, let's make a copy of this function. 42 00:03:12,870 --> 00:03:15,390 The logic is going to mainly be the same. 43 00:03:15,930 --> 00:03:19,200 Instead, we're going to print the verified field. 44 00:03:19,560 --> 00:03:24,360 Everything in the second function should be updated to log the verified fields. 45 00:03:26,930 --> 00:03:32,570 Our functions are already inside the main function instead of directly printing these fields. 46 00:03:32,630 --> 00:03:36,290 We will call both functions with the my account variable. 47 00:03:41,920 --> 00:03:45,010 After making those changes will encounter an error. 48 00:03:45,310 --> 00:03:50,500 Take a closer look at the error the compiler is informing us of an ownership error. 49 00:03:50,860 --> 00:03:54,550 It states that the my account variable has been removed. 50 00:03:54,820 --> 00:03:56,620 What exactly does that mean? 51 00:03:57,130 --> 00:04:01,240 As we learned earlier, variables take ownership of a value. 52 00:04:01,540 --> 00:04:05,830 The My Account variable has ownership of the bank account value. 53 00:04:06,190 --> 00:04:13,240 However, we're passing on the my account variable to the print balance function during this process. 54 00:04:13,390 --> 00:04:16,630 Russ gives ownership to the print balance function. 55 00:04:17,019 --> 00:04:24,430 Therefore, the my account variable in the main function has lost ownership by having ownership of the 56 00:04:24,430 --> 00:04:25,150 variable. 57 00:04:25,330 --> 00:04:31,780 The print balance function will be able to access the value stored in the variable after the function 58 00:04:31,780 --> 00:04:32,860 is finished running. 59 00:04:33,040 --> 00:04:36,610 Russ will release memory allocated for the variable. 60 00:04:36,940 --> 00:04:40,210 It's dropping the value, which leads us to our error. 61 00:04:40,840 --> 00:04:44,500 The print verified function wants access to the variable. 62 00:04:44,800 --> 00:04:46,720 At this point, it's been dropped. 63 00:04:47,020 --> 00:04:51,790 Therefore, the print verified function will not be able to print the variable. 64 00:04:52,180 --> 00:04:54,700 The error message should start to make sense. 65 00:04:55,000 --> 00:04:58,630 It's telling us the ownership of a variable has been moved. 66 00:04:59,140 --> 00:05:02,890 We can resolve our issue by using a feature called borrowing. 67 00:05:03,250 --> 00:05:07,060 For example, let's say your neighbor wants to borrow your lawnmower. 68 00:05:07,390 --> 00:05:12,790 The idea of borrowing is to give temporary possession of something you own to someone else. 69 00:05:13,150 --> 00:05:17,140 Assuming your neighbor is trustworthy, they will give back your lawnmower. 70 00:05:17,500 --> 00:05:20,530 This idea of borrowing can apply to programming. 71 00:05:21,160 --> 00:05:24,700 Rust allows us to borrow variables from other functions. 72 00:05:24,970 --> 00:05:31,900 We can modify our functions to borrow the variable rather than taking ownership before the type annotation 73 00:05:31,900 --> 00:05:33,040 in both functions. 74 00:05:33,220 --> 00:05:35,710 We're going to add an ampersand symbol. 75 00:05:38,210 --> 00:05:44,870 By adding this symbol, Russ will prevent the function from taking ownership away and said it'll allow 76 00:05:44,870 --> 00:05:50,570 the function to borrow the value for reading purposes after the function is finished running. 77 00:05:50,690 --> 00:05:52,610 Rust will not drop the value. 78 00:05:52,970 --> 00:05:59,070 Ownership will continue to belong to the my account variable inside the main function. 79 00:05:59,090 --> 00:06:03,560 We're going to add the ampersand symbol to the arguments in both functions. 80 00:06:06,190 --> 00:06:10,640 We're telling Russ to allow these functions to borrow the variables value. 81 00:06:11,020 --> 00:06:13,450 The functions will ask to borrow the value. 82 00:06:13,690 --> 00:06:20,140 The ampersand symbol will need to be added to the argument list and function calls after making those 83 00:06:20,140 --> 00:06:20,800 changes. 84 00:06:21,040 --> 00:06:23,080 The compiler will stop complaining. 85 00:06:23,470 --> 00:06:25,690 Let's try compiling our project. 86 00:06:28,270 --> 00:06:30,970 As expected, we get the same output. 87 00:06:31,360 --> 00:06:34,420 This behavior is very important to understand. 88 00:06:34,810 --> 00:06:36,640 Rust is memory efficient. 89 00:06:36,940 --> 00:06:40,900 By default, it can transfer ownership across functions. 90 00:06:41,230 --> 00:06:47,410 If that's not what you want, you can override behavior by telling the compiler to borrow the value.