1 00:00:06,660 --> 00:00:07,493 - [Instructor] In this section, 2 00:00:07,493 --> 00:00:10,080 we're going to see how to return a mutable reference 3 00:00:10,080 --> 00:00:11,370 from a function. 4 00:00:11,370 --> 00:00:12,900 But first, a quick reminder 5 00:00:12,900 --> 00:00:15,750 of how to return an immutable reference from a function. 6 00:00:15,750 --> 00:00:16,590 Here's an example, 7 00:00:16,590 --> 00:00:19,800 similar to what we saw at the end of the previous demo. 8 00:00:19,800 --> 00:00:23,250 I've got a function called get_first_word 9 00:00:23,250 --> 00:00:26,580 and it takes in a string slice 10 00:00:26,580 --> 00:00:29,130 and it returns a string slice. 11 00:00:29,130 --> 00:00:30,480 Let's actually just go through this 12 00:00:30,480 --> 00:00:32,253 to see what it was going to do. 13 00:00:33,180 --> 00:00:35,430 At the top, I have a string, 14 00:00:35,430 --> 00:00:36,270 I'll draw it here. 15 00:00:36,270 --> 00:00:40,893 S is my string and it contains hello world. 16 00:00:42,060 --> 00:00:42,893 Okey-dokey. 17 00:00:43,740 --> 00:00:46,590 And then I pass a reference to string. 18 00:00:46,590 --> 00:00:49,960 Basically I pass a string reference 19 00:00:51,120 --> 00:00:53,460 into this parameter here, 20 00:00:53,460 --> 00:00:55,740 which is of type &str. 21 00:00:55,740 --> 00:00:58,980 And remember, you can always take a string reference 22 00:00:58,980 --> 00:01:00,690 and assign it to a string slice. 23 00:01:00,690 --> 00:01:01,740 That is allowed. 24 00:01:01,740 --> 00:01:04,680 That's one of the built-in rules in Rust. 25 00:01:04,680 --> 00:01:06,510 So we end up with this variable here. 26 00:01:06,510 --> 00:01:11,457 This is a slice that basically points there like that 27 00:01:11,457 --> 00:01:14,790 and it knows that it's like 11 or 12 characters long. 28 00:01:14,790 --> 00:01:16,804 And then if you remember what the function does, 29 00:01:16,804 --> 00:01:20,640 it kind of finds the position of first space 30 00:01:20,640 --> 00:01:24,480 and then it returns a sub-portion of the string. 31 00:01:24,480 --> 00:01:25,980 So it takes the string 32 00:01:25,980 --> 00:01:28,140 and it returns, starting at position zero, 33 00:01:28,140 --> 00:01:30,840 up to but not including the position of the space, 34 00:01:30,840 --> 00:01:35,840 it returns a slice that refers to this portion. 35 00:01:36,150 --> 00:01:39,000 Okay, so if I can draw that like so, 36 00:01:39,000 --> 00:01:42,990 the slice that it returns basically indicates 37 00:01:42,990 --> 00:01:47,370 that's the starting point and five characters in size. 38 00:01:47,370 --> 00:01:49,080 So it kind of indicates 39 00:01:49,080 --> 00:01:54,030 that slice there is what gets returned. 40 00:01:54,030 --> 00:01:56,013 Okay, that's the return slice here. 41 00:01:57,060 --> 00:01:59,373 And we assign that to r1. 42 00:02:00,600 --> 00:02:02,130 So when we print r1, 43 00:02:02,130 --> 00:02:05,223 it prints, well basically it prints hello. 44 00:02:06,180 --> 00:02:09,030 Right, so that actually was quite a nice example 45 00:02:09,030 --> 00:02:12,483 of how you'd pass references into and out of a function. 46 00:02:13,320 --> 00:02:14,790 But of course in this example, 47 00:02:14,790 --> 00:02:18,120 all the references here are immutable. 48 00:02:18,120 --> 00:02:19,020 So what we're gonna look at now 49 00:02:19,020 --> 00:02:21,180 is how to deal with mutable references. 50 00:02:21,180 --> 00:02:23,040 And to be honest, it's mostly the same. 51 00:02:23,040 --> 00:02:26,340 It's just that you put the mut keyword here and there. 52 00:02:26,340 --> 00:02:28,080 So this is how you specify 53 00:02:28,080 --> 00:02:31,050 that a function returns a mutable reference type. 54 00:02:31,050 --> 00:02:34,590 You say it's a mutable reference to some type. 55 00:02:34,590 --> 00:02:37,260 It means that what you pass back to the caller, 56 00:02:37,260 --> 00:02:40,200 the caller is then allowed to change, 57 00:02:40,200 --> 00:02:41,910 you know, the value you've returned. 58 00:02:41,910 --> 00:02:43,380 So that's how you specify 59 00:02:43,380 --> 00:02:46,170 that you return a mutable reference. 60 00:02:46,170 --> 00:02:47,460 To actually do it, 61 00:02:47,460 --> 00:02:51,900 then you specify an &mut well. 62 00:02:51,900 --> 00:02:54,630 You take some value of the designated type 63 00:02:54,630 --> 00:02:56,880 and you return a mutable reference to it 64 00:02:56,880 --> 00:02:58,530 back to the caller. 65 00:02:58,530 --> 00:03:00,045 So the caller can then change the value 66 00:03:00,045 --> 00:03:01,983 that you're referring to. 67 00:03:03,090 --> 00:03:05,820 So, dos and don'ts, things to remember, 68 00:03:05,820 --> 00:03:08,070 do comply with the borrow checker. 69 00:03:08,070 --> 00:03:09,960 Remember the borrow checker in Rust. 70 00:03:09,960 --> 00:03:11,580 The compiler's very fussy. 71 00:03:11,580 --> 00:03:13,680 You can only have one mutable reference 72 00:03:13,680 --> 00:03:15,450 to an object at a time. 73 00:03:15,450 --> 00:03:17,670 Okay, and the rules still apply here. 74 00:03:17,670 --> 00:03:21,300 You can only have one mutable reference at a time. 75 00:03:21,300 --> 00:03:24,210 Also, don't return a dangling reference. 76 00:03:24,210 --> 00:03:26,940 Don't try to return a reference to a local object. 77 00:03:26,940 --> 00:03:28,710 The compiler will complain. 78 00:03:28,710 --> 00:03:31,320 It'll say this object is gonna go out of scope 79 00:03:31,320 --> 00:03:32,550 at the end of the function. 80 00:03:32,550 --> 00:03:33,690 You can't return a reference 81 00:03:33,690 --> 00:03:36,240 because it's gonna disappear in half a second. 82 00:03:36,240 --> 00:03:38,250 So don't return references 83 00:03:38,250 --> 00:03:41,070 to local stack-based objects. 84 00:03:41,070 --> 00:03:43,440 Right, and now imagine that you call the function 85 00:03:43,440 --> 00:03:45,780 which does return a mutable reference 86 00:03:45,780 --> 00:03:46,740 and you want to assign that 87 00:03:46,740 --> 00:03:48,933 to a variable in your call in function. 88 00:03:50,280 --> 00:03:51,113 Simple enough 89 00:03:51,113 --> 00:03:52,470 using implicit type in, 90 00:03:52,470 --> 00:03:53,910 if you call a function 91 00:03:53,910 --> 00:03:56,070 that returns a mutable reference. 92 00:03:56,070 --> 00:04:00,060 Implicitly, that variable would be a mutable reference. 93 00:04:00,060 --> 00:04:02,400 You can use explicit typing, if you prefer. 94 00:04:02,400 --> 00:04:05,460 You can say r is a mutable reference 95 00:04:05,460 --> 00:04:07,800 to whatever type it returns. 96 00:04:07,800 --> 00:04:09,600 So again, we have the choice. 97 00:04:09,600 --> 00:04:11,760 You can either use implicit typing 98 00:04:11,760 --> 00:04:14,250 based on the return type of the function, 99 00:04:14,250 --> 00:04:16,320 or you can use explicit typing 100 00:04:16,320 --> 00:04:18,570 if you feel that that makes your code more readable. 101 00:04:18,570 --> 00:04:19,770 Up to you, really. 102 00:04:19,770 --> 00:04:22,590 Personally, I prefer implicit typing 103 00:04:22,590 --> 00:04:24,840 because there's less noise. 104 00:04:24,840 --> 00:04:27,963 It makes the code easier to read and understand. 105 00:04:28,950 --> 00:04:30,930 Right, well that was actually quite straightforward. 106 00:04:30,930 --> 00:04:34,320 We'll have a look at an example and then we'll run it. 107 00:04:34,320 --> 00:04:35,610 So here's the example. 108 00:04:35,610 --> 00:04:37,500 In my main code, 109 00:04:37,500 --> 00:04:41,530 I'll comment out the example that we had before 110 00:04:42,385 --> 00:04:45,240 and I'll uncomment the example that we need now. 111 00:04:45,240 --> 00:04:46,403 demo_returning_mutable_reference. 112 00:04:48,210 --> 00:04:49,113 And it's here. 113 00:04:49,950 --> 00:04:51,330 So I have a function, 114 00:04:51,330 --> 00:04:53,380 it takes a mutable reference to a string, 115 00:04:54,450 --> 00:04:55,890 and here is, 116 00:04:55,890 --> 00:04:59,670 well obviously the original object also has to be mutable 117 00:04:59,670 --> 00:05:01,440 otherwise you can't take a mutable reference 118 00:05:01,440 --> 00:05:02,700 to it in the first place. 119 00:05:02,700 --> 00:05:05,490 I've got a mutable string, hello, 120 00:05:05,490 --> 00:05:07,050 I take a mutable reference, 121 00:05:07,050 --> 00:05:09,150 or as the Rustation would say, 122 00:05:09,150 --> 00:05:11,220 I borrow it mutably. 123 00:05:11,220 --> 00:05:14,100 I pass a mutable reference into here. 124 00:05:14,100 --> 00:05:15,030 So that's basically, 125 00:05:15,030 --> 00:05:17,853 this is a reference to that string. 126 00:05:18,810 --> 00:05:19,890 I append, 127 00:05:19,890 --> 00:05:21,780 so it's gonna be hello world. 128 00:05:21,780 --> 00:05:23,370 And I return s. 129 00:05:23,370 --> 00:05:26,610 Well, s is a mutable reference. 130 00:05:26,610 --> 00:05:28,620 So when you return s, remember, 131 00:05:28,620 --> 00:05:29,700 when you have an expression, 132 00:05:29,700 --> 00:05:32,833 it's as if you returned it as a statement 133 00:05:32,833 --> 00:05:36,390 but across the Rustation we'd write it that way. 134 00:05:36,390 --> 00:05:41,390 So, return s as a mutable reference. 135 00:05:41,700 --> 00:05:44,220 So this is a mutable reference 136 00:05:44,220 --> 00:05:46,200 and that's what we said we'd return. 137 00:05:46,200 --> 00:05:49,260 So r is a mutable reference 138 00:05:49,260 --> 00:05:51,060 to the same string as we've been dealing with. 139 00:05:51,060 --> 00:05:53,850 R is basically a mutable reference to this 140 00:05:53,850 --> 00:05:55,980 which means we can add something else. 141 00:05:55,980 --> 00:05:57,330 We can add something else. 142 00:05:57,330 --> 00:05:59,700 So it was, hello, 143 00:05:59,700 --> 00:06:01,830 we appended world, 144 00:06:01,830 --> 00:06:03,120 and now we're appending, 145 00:06:03,120 --> 00:06:03,953 and goodbye. 146 00:06:03,953 --> 00:06:05,760 hello world and goodbye. 147 00:06:05,760 --> 00:06:09,210 And then finally we print out the reference string 148 00:06:09,210 --> 00:06:10,530 like so. 149 00:06:10,530 --> 00:06:12,960 I feel good about this example. 150 00:06:12,960 --> 00:06:14,160 I think it's gonna work. 151 00:06:18,240 --> 00:06:21,633 Okay, so hello world and goodbye. 152 00:06:22,680 --> 00:06:23,513 There we are. 153 00:06:23,513 --> 00:06:25,170 So that is the end of the lesson. 154 00:06:25,170 --> 00:06:28,680 We've talked about how to pass parameters into a function 155 00:06:28,680 --> 00:06:31,948 by value, by reference, or by mutable reference. 156 00:06:31,948 --> 00:06:34,140 The main thing to be careful there 157 00:06:34,140 --> 00:06:36,150 when you're passing by value 158 00:06:36,150 --> 00:06:38,760 is whether you are moving ownership of the object 159 00:06:38,760 --> 00:06:43,350 into the function and losing it from your call in function. 160 00:06:43,350 --> 00:06:45,360 So you might prefer to pass by reference 161 00:06:45,360 --> 00:06:48,030 which borrows the value but doesn't own it 162 00:06:48,030 --> 00:06:50,790 and mutable reference if you need to change the value. 163 00:06:50,790 --> 00:06:52,980 And then of course you can return for a function 164 00:06:52,980 --> 00:06:54,570 you can return a value, 165 00:06:54,570 --> 00:06:57,300 transfer ownership back to the caller, 166 00:06:57,300 --> 00:07:00,120 or you can return a reference or a mutable reference. 167 00:07:00,120 --> 00:07:01,710 And then you have to be careful 168 00:07:01,710 --> 00:07:03,450 that the thing you're referring to 169 00:07:03,450 --> 00:07:06,750 has a long enough lifetime so it doesn't disappear 170 00:07:06,750 --> 00:07:10,653 before the calling function can actually use the reference.