1 00:00:06,690 --> 00:00:09,480 - It's very common to pass structure objects 2 00:00:09,480 --> 00:00:10,563 into a function. 3 00:00:11,460 --> 00:00:14,340 This enables you to pass a whole object into a function, 4 00:00:14,340 --> 00:00:16,530 a lot of data all in one go, 5 00:00:16,530 --> 00:00:17,739 much better than passing 6 00:00:17,739 --> 00:00:20,160 a whole load of individual parameters. 7 00:00:20,160 --> 00:00:21,960 You can just pass a single structure, 8 00:00:21,960 --> 00:00:24,480 and all of its data immediately gets passed 9 00:00:24,480 --> 00:00:27,930 into the other function in one fell swoop. 10 00:00:27,930 --> 00:00:29,850 So that's quite handy. 11 00:00:29,850 --> 00:00:32,700 So when you pass values into a function, 12 00:00:32,700 --> 00:00:34,170 you've got two different ways to do it. 13 00:00:34,170 --> 00:00:37,590 You can pass by value, which is what we'll discuss now, 14 00:00:37,590 --> 00:00:39,360 or you can pass by reference, 15 00:00:39,360 --> 00:00:41,760 which we'll discuss a bit later. 16 00:00:41,760 --> 00:00:44,130 So let's imagine we have a function. 17 00:00:44,130 --> 00:00:47,550 This function receives a structure parameter by value. 18 00:00:47,550 --> 00:00:51,810 There's no ampersands, it's not receiving a reference, 19 00:00:51,810 --> 00:00:55,110 it's receiving a structure by value, 20 00:00:55,110 --> 00:00:57,510 and it prints the name and the salary 21 00:00:57,510 --> 00:00:59,220 and the fulltime flag. 22 00:00:59,220 --> 00:01:00,630 Now, the name of the function, 23 00:01:00,630 --> 00:01:03,090 I've called it consume employee, 24 00:01:03,090 --> 00:01:05,430 gives you an indication of what's gonna happen 25 00:01:05,430 --> 00:01:07,320 when we call the function. 26 00:01:07,320 --> 00:01:10,560 So let's see some high level function. 27 00:01:10,560 --> 00:01:11,910 Here we are. 28 00:01:11,910 --> 00:01:16,230 And in here, I declare e1. 29 00:01:16,230 --> 00:01:18,990 So e1 is my employee, 30 00:01:18,990 --> 00:01:23,100 the name, and the salary, and the region. 31 00:01:23,100 --> 00:01:27,390 And then I pass e1 basically up into the function above. 32 00:01:27,390 --> 00:01:32,360 Okay, so e1 gets passed up into here. 33 00:01:32,360 --> 00:01:35,190 So what happens now when you pass by value? 34 00:01:35,190 --> 00:01:37,800 Remember, this is tricky in Rust. 35 00:01:37,800 --> 00:01:40,320 When you pass something by value, what happens? 36 00:01:40,320 --> 00:01:42,030 It depends on whether the type 37 00:01:42,030 --> 00:01:45,450 implements the Copy trait or not. 38 00:01:45,450 --> 00:01:48,593 So what I'm telling you for a fact at the moment, 39 00:01:48,593 --> 00:01:50,400 the structure that we've got, 40 00:01:50,400 --> 00:01:52,620 the employee doesn't implement the Copy trait. 41 00:01:52,620 --> 00:01:55,230 We haven't really seen how to do that yet. 42 00:01:55,230 --> 00:01:58,260 We can and we will, but we haven't done it yet. 43 00:01:58,260 --> 00:01:59,820 So at the moment, 44 00:01:59,820 --> 00:02:04,200 the Employee structure doesn't implement the Copy trait. 45 00:02:04,200 --> 00:02:07,260 So what's gonna happen is it will copy, 46 00:02:07,260 --> 00:02:12,260 it will still copy the data into this employee here, e. 47 00:02:14,070 --> 00:02:16,530 Okay, so the data will be copied into there, 48 00:02:16,530 --> 00:02:20,730 the name, and the salary, and the fulltime status. 49 00:02:20,730 --> 00:02:23,220 A move occurs, basically. 50 00:02:23,220 --> 00:02:26,580 The employee object here used to own the data. 51 00:02:26,580 --> 00:02:30,090 That data is moved into the other structure up here. 52 00:02:30,090 --> 00:02:33,900 The data was moved into this structure object up here. 53 00:02:33,900 --> 00:02:38,340 And this structure basically goes away. 54 00:02:38,340 --> 00:02:41,460 It becomes vacated, a move occurs. 55 00:02:41,460 --> 00:02:45,932 So our function down here loses ownership of the data. 56 00:02:45,932 --> 00:02:47,880 It's gone effectively. 57 00:02:47,880 --> 00:02:50,733 That data has been moved up to here. 58 00:02:51,900 --> 00:02:54,150 So we can use that data in the function. 59 00:02:54,150 --> 00:02:57,030 We can access the name and the salary and so on. 60 00:02:57,030 --> 00:03:01,470 But of course, when this structure goes at the scope, 61 00:03:01,470 --> 00:03:06,390 it will be popped off the stack and it disappears, okay? 62 00:03:06,390 --> 00:03:09,150 So if you do pass a structure 63 00:03:09,150 --> 00:03:12,150 and the structure doesn't implement Copy, 64 00:03:12,150 --> 00:03:14,490 then by passing the structure into a function, 65 00:03:14,490 --> 00:03:17,130 you basically lose that object. 66 00:03:17,130 --> 00:03:19,110 You pass the object into the function, 67 00:03:19,110 --> 00:03:22,260 that receiving function acquires ownership. 68 00:03:22,260 --> 00:03:23,790 And at the end of that function, 69 00:03:23,790 --> 00:03:25,770 the object is dropped, it's destroyed. 70 00:03:25,770 --> 00:03:29,220 It means you can't then use the object anymore down here. 71 00:03:29,220 --> 00:03:31,620 So to summarize the rules, 72 00:03:31,620 --> 00:03:34,590 what happens when you pass a structure into a function? 73 00:03:34,590 --> 00:03:36,750 It depends on whether the structure implements 74 00:03:36,750 --> 00:03:38,700 the Copy trait or not. 75 00:03:38,700 --> 00:03:42,150 If it did, then it would behave more like an integer. 76 00:03:42,150 --> 00:03:43,830 A bitwise copy of the structure 77 00:03:43,830 --> 00:03:45,783 would be passed into the function. 78 00:03:46,830 --> 00:03:49,950 The original function retains ownership 79 00:03:49,950 --> 00:03:51,780 and can use the structure afterwards 80 00:03:51,780 --> 00:03:53,670 as if you were passing integer, 81 00:03:53,670 --> 00:03:55,514 which implement the Copy trait. 82 00:03:55,514 --> 00:03:59,310 If you don't implement the Copy trait for the structure, 83 00:03:59,310 --> 00:04:02,370 and many structures don't implement Copy, 84 00:04:02,370 --> 00:04:05,460 then ownership of the structure is moved 85 00:04:05,460 --> 00:04:07,440 into the called function, 86 00:04:07,440 --> 00:04:09,270 and the caller loses ownership 87 00:04:09,270 --> 00:04:12,030 and can't use the object anymore. 88 00:04:12,030 --> 00:04:13,580 So you have to be careful here. 89 00:04:14,520 --> 00:04:16,800 Right, well, let's have a look at the example. 90 00:04:16,800 --> 00:04:18,660 Same project as before. 91 00:04:18,660 --> 00:04:20,850 The files involved, obviously, mytypes, 92 00:04:20,850 --> 00:04:23,670 which defines the Employee structure. 93 00:04:23,670 --> 00:04:26,550 The main code, which calls my demo function. 94 00:04:26,550 --> 00:04:28,260 And my demo function this time is 95 00:04:28,260 --> 00:04:32,220 in demo_struct_pass_value, pass by value. 96 00:04:32,220 --> 00:04:33,480 Okay, so we'll run the project 97 00:04:33,480 --> 00:04:34,620 once we've had a look at the code. 98 00:04:34,620 --> 00:04:36,780 Let's have a look at the code. 99 00:04:36,780 --> 00:04:39,150 So quick reminder, mytypes, 100 00:04:39,150 --> 00:04:42,510 my Employee structure doesn't implement the Copy trait. 101 00:04:42,510 --> 00:04:45,330 We haven't seen how to do it yet, so it doesn't. 102 00:04:45,330 --> 00:04:46,710 We will see that later. 103 00:04:46,710 --> 00:04:50,310 But at the moment, our structure doesn't implement Copy. 104 00:04:50,310 --> 00:04:53,610 So when we pass by value, a move will occur. 105 00:04:53,610 --> 00:04:55,320 In my main code, 106 00:04:55,320 --> 00:04:59,490 let's uncomment the demo for this part of the example, 107 00:04:59,490 --> 00:05:03,723 demo_struct_pass_value, and it's here. 108 00:05:06,720 --> 00:05:09,990 So I have a function called consume_employee. 109 00:05:09,990 --> 00:05:14,520 It receives an employee and acquires ownership, 110 00:05:14,520 --> 00:05:16,290 accesses the data. 111 00:05:16,290 --> 00:05:17,640 And then at the end of the function, 112 00:05:17,640 --> 00:05:20,040 the employee object will be dropped and it's gone. 113 00:05:20,040 --> 00:05:22,560 It'll be popped off the stack and that's the end of that. 114 00:05:22,560 --> 00:05:26,073 So my calling function creates the original employee, e1, 115 00:05:27,180 --> 00:05:30,420 and it's John again, good old John. 116 00:05:30,420 --> 00:05:34,380 When I pass the object into the function by value, 117 00:05:34,380 --> 00:05:37,830 my code loses ownership. 118 00:05:37,830 --> 00:05:40,560 That employee is now owned by this function, 119 00:05:40,560 --> 00:05:43,800 which uses it and then loses it. 120 00:05:43,800 --> 00:05:46,890 Up here, I can't use the employee again. 121 00:05:46,890 --> 00:05:48,270 I've lost ownership. 122 00:05:48,270 --> 00:05:52,260 The object has moved away into this variable here. 123 00:05:52,260 --> 00:05:54,720 I can't use the original variable up here, okay? 124 00:05:54,720 --> 00:05:56,010 It's defunct. 125 00:05:56,010 --> 00:05:58,830 If I try to, I'm gonna get an error. 126 00:05:58,830 --> 00:06:02,010 It'll say you can't try to borrow this object 127 00:06:02,010 --> 00:06:04,470 because you've moved ownership away into that function. 128 00:06:04,470 --> 00:06:05,850 It's gone now. 129 00:06:05,850 --> 00:06:06,870 So if I ran the code now, 130 00:06:06,870 --> 00:06:10,773 I'd get a compiler error on line 17. 131 00:06:12,960 --> 00:06:14,643 Let's see, cargo check. 132 00:06:17,940 --> 00:06:19,500 Right. 133 00:06:19,500 --> 00:06:22,350 So I've created an employee. 134 00:06:22,350 --> 00:06:25,590 Employee doesn't implement the Copy trait, 135 00:06:25,590 --> 00:06:27,660 meaning when you pass by value, 136 00:06:27,660 --> 00:06:29,220 it will be moved away from you. 137 00:06:29,220 --> 00:06:30,480 You'll lose it. 138 00:06:30,480 --> 00:06:31,440 So it's saying, "What?" 139 00:06:31,440 --> 00:06:32,490 Bear that in mind. 140 00:06:32,490 --> 00:06:36,600 So when you pass e1 into the consume_employee function, 141 00:06:36,600 --> 00:06:39,510 the function did consume it, hence the name. 142 00:06:39,510 --> 00:06:42,630 So the value was moved away from you here into the function. 143 00:06:42,630 --> 00:06:44,280 You don't own it anymore. 144 00:06:44,280 --> 00:06:48,090 So then we need to access the name here on line 17, 145 00:06:48,090 --> 00:06:50,970 you can't try to access the name. 146 00:06:50,970 --> 00:06:53,280 The print function is trying to borrow the employee, 147 00:06:53,280 --> 00:06:54,113 trying to reference it. 148 00:06:54,113 --> 00:06:58,350 It can't because the object has been moved previously. 149 00:06:58,350 --> 00:07:01,650 You can't use the value after it's been moved away. 150 00:07:01,650 --> 00:07:04,080 So, I mean, obviously, one solution would be 151 00:07:04,080 --> 00:07:06,780 to implement the Copy trait on employee. 152 00:07:06,780 --> 00:07:09,540 Another solution would be to pass by reference, 153 00:07:09,540 --> 00:07:10,890 and we'll look at that later. 154 00:07:10,890 --> 00:07:14,670 But if you do pass by value and it doesn't implement Copy, 155 00:07:14,670 --> 00:07:18,840 you will lose the object when you pass the value in, right? 156 00:07:18,840 --> 00:07:21,330 So let me comment out this code for now 157 00:07:21,330 --> 00:07:24,540 and I'll just try running the application as it stands, 158 00:07:24,540 --> 00:07:26,220 just to confirm that it does actually work. 159 00:07:26,220 --> 00:07:27,690 Yes, that compiles. 160 00:07:27,690 --> 00:07:28,563 Let's run it. 161 00:07:31,654 --> 00:07:36,190 Okay, so from the top, I'm in demo_struct_pass_value. 162 00:07:37,110 --> 00:07:38,310 Here I am. 163 00:07:38,310 --> 00:07:41,430 And I create my employee, I pass it, 164 00:07:41,430 --> 00:07:43,680 I move it into that function. 165 00:07:43,680 --> 00:07:45,120 It prints the employee details. 166 00:07:45,120 --> 00:07:48,295 John earns 1K, doesn't say per annum, 167 00:07:48,295 --> 00:07:53,295 maybe that's per minute, and he's not a full-time employee. 168 00:07:53,340 --> 00:07:55,380 The employee object will be dropped here. 169 00:07:55,380 --> 00:07:57,044 So it's gone now, 170 00:07:57,044 --> 00:07:59,820 which means we couldn't access it anymore. 171 00:07:59,820 --> 00:08:02,310 Right, so pass by value for structures 172 00:08:02,310 --> 00:08:04,680 is potentially fraught 173 00:08:04,680 --> 00:08:08,100 because you could and you will lose the object 174 00:08:08,100 --> 00:08:11,130 if the object doesn't implement the Copy trait. 175 00:08:11,130 --> 00:08:15,450 So, maybe you can pass it by reference instead 176 00:08:15,450 --> 00:08:17,370 so that you don't lose ownership. 177 00:08:17,370 --> 00:08:19,970 That's what we're going to look at in the next demo.