1
00:00:04,810 --> 00:00:06,999
Hopefully, you've had a chance to try the exercise
2
00:00:07,000 --> 00:00:09,390
we introduced at the end of the previous module.
3
00:00:09,580 --> 00:00:11,469
We're going to be talking all about that exercise
4
00:00:11,470 --> 00:00:12,460
in this video.
5
00:00:13,890 --> 00:00:15,719
First, we're going to take a look at the starting
6
00:00:15,720 --> 00:00:18,160
code of the exercise in a bit more detail.
7
00:00:18,540 --> 00:00:20,699
Then, we'll see one possible way
8
00:00:20,700 --> 00:00:22,340
to complete the exercise.
9
00:00:23,010 --> 00:00:25,259
After that, we'll take a look at some solutions
10
00:00:25,260 --> 00:00:27,019
you might have tried that don't work
11
00:00:27,020 --> 00:00:29,240
and result in compiler errors instead.
12
00:00:29,700 --> 00:00:30,779
Getting compiler errors
13
00:00:30,780 --> 00:00:33,200
and fixing them is where the learning happens.
14
00:00:33,720 --> 00:00:35,939
If you got errors while you're working on the exercise,
15
00:00:35,940 --> 00:00:37,799
that's awesome! We'll be addressing some
16
00:00:37,800 --> 00:00:40,190
of the common ones that might be what you've seen.
17
00:00:40,830 --> 00:00:42,839
We'll round out this module by talking about why
18
00:00:42,840 --> 00:00:44,669
this task feels harder than it would
19
00:00:44,670 --> 00:00:45,920
in other languages.
20
00:00:47,270 --> 00:00:49,159
Let's take a close look at the starting code of
21
00:00:49,160 --> 00:00:50,290
the exercise.
22
00:00:51,610 --> 00:00:53,439
There are a few things to notice in this code that are
23
00:00:53,440 --> 00:00:54,720
affected by ownership.
24
00:00:55,480 --> 00:00:57,960
s is a String, which owns its data.
25
00:00:58,420 --> 00:01:00,289
We want to use s when we call the
26
00:01:00,290 --> 00:01:01,660
pluralize function.
27
00:01:02,330 --> 00:01:04,409
We also want to use s in the println
28
00:01:04,410 --> 00:01:06,730
call after the call to pluralize.
29
00:01:08,180 --> 00:01:10,849
There are many possible solutions to this exercise.
30
00:01:10,850 --> 00:01:12,280
Let's take a look at one of them.
31
00:01:13,680 --> 00:01:16,080
We'll start by filling in the pluralize function.
32
00:01:16,660 --> 00:01:18,609
We want the function to take one parameter
33
00:01:18,610 --> 00:01:19,680
of type String,
34
00:01:19,810 --> 00:01:20,939
and we'll call that parameter
35
00:01:20,940 --> 00:01:22,939
singular. The return
36
00:01:22,940 --> 00:01:25,270
type of the function will also be a String.
37
00:01:26,720 --> 00:01:28,809
The body of pluralize will take singular
38
00:01:28,810 --> 00:01:30,860
and add the string, s, to the end.
39
00:01:31,720 --> 00:01:33,579
Because we don't have a semicolon at the end of the
40
00:01:33,580 --> 00:01:34,200
line,
41
00:01:34,420 --> 00:01:36,459
the concatenated string will be the return value
42
00:01:36,460 --> 00:01:37,320
of the function.
43
00:01:38,820 --> 00:01:40,699
Now we can call the pluralize function from
44
00:01:40,700 --> 00:01:42,989
main. The arguments of pluralize
45
00:01:42,990 --> 00:01:44,870
will be a clone of s
46
00:01:44,970 --> 00:01:47,409
and we'll store the result in a new variable,
47
00:01:47,410 --> 00:01:49,439
pl. Now we can
48
00:01:49,440 --> 00:01:50,799
use both s
49
00:01:50,800 --> 00:01:53,090
and pl in the println call.
50
00:01:54,540 --> 00:01:55,619
This solution works;
51
00:01:55,620 --> 00:01:56,540
here's some proof.
52
00:01:58,580 --> 00:02:00,899
OK. Now, let's take a look at some solutions
53
00:02:00,900 --> 00:02:02,210
that don't quite work,
54
00:02:02,270 --> 00:02:04,970
and we'll learn more about ownership in the process.
55
00:02:06,390 --> 00:02:07,709
If we didn't clone s
56
00:02:07,710 --> 00:02:09,899
and passed the clone string to pluralize,
57
00:02:09,900 --> 00:02:10,959
we'd get an error.
58
00:02:14,640 --> 00:02:16,789
There it says use of moved value:
59
00:02:16,790 --> 00:02:18,889
`s` and shows the s was moved
60
00:02:18,890 --> 00:02:20,260
into pluralize.
61
00:02:21,100 --> 00:02:23,019
That means pluralize now owns s,
62
00:02:23,020 --> 00:02:25,510
and s can be cleaned up at the end of pluralize.
63
00:02:25,630 --> 00:02:27,609
So, we can't use s again in the println
64
00:02:27,610 --> 00:02:28,800
in main.
65
00:02:29,610 --> 00:02:31,909
That's why the working solution clones s.
66
00:02:31,910 --> 00:02:33,929
The clone is what is moved into pluralize,
67
00:02:33,930 --> 00:02:36,470
and main continues to own s.
68
00:02:37,940 --> 00:02:39,799
If we clone s in the println
69
00:02:39,800 --> 00:02:42,049
instead of as the argument to pluralize,
70
00:02:42,050 --> 00:02:43,810
we'll get essentially the same error.
71
00:02:45,650 --> 00:02:47,479
Again, we can't use s at all in the
72
00:02:47,480 --> 00:02:50,170
println because it's been moved into pluralize.
73
00:02:50,990 --> 00:02:53,299
While calling clone is part of the correct solution,
74
00:02:53,300 --> 00:02:55,210
it does matter where we call it.
75
00:02:56,560 --> 00:02:58,899
You might not have used an intermediate variable.
76
00:02:58,900 --> 00:03:00,759
You might have called pluralize from the println
77
00:03:00,760 --> 00:03:02,589
directly.
78
00:03:02,590 --> 00:03:03,819
As long as you called clone,
79
00:03:03,820 --> 00:03:05,210
this would also work.
80
00:03:08,510 --> 00:03:10,389
However, if the clone isn't in
81
00:03:10,390 --> 00:03:12,459
the pluralize call, we'll get slightly different
82
00:03:12,460 --> 00:03:13,200
errors.
83
00:03:15,040 --> 00:03:16,899
This time, the error says, cannot
84
00:03:16,900 --> 00:03:19,020
move out of `s`because it is borrowed.
85
00:03:19,860 --> 00:03:21,689
This happens because println borrows its
86
00:03:21,690 --> 00:03:22,480
arguments.
87
00:03:23,130 --> 00:03:24,800
So, it borrows s first,
88
00:03:25,010 --> 00:03:26,879
and then we try to move s into the
89
00:03:26,880 --> 00:03:27,950
pluralize call.
90
00:03:29,360 --> 00:03:31,249
We haven't talked about borrowing yet, but
91
00:03:31,250 --> 00:03:32,760
we will in the next module.
92
00:03:33,050 --> 00:03:34,879
The important thing to know for now is that you
93
00:03:34,880 --> 00:03:37,020
can't move a value while it's borrowed.
94
00:03:38,410 --> 00:03:40,629
This exercise involves some string manipulation
95
00:03:40,630 --> 00:03:43,110
and a function. In many languages,
96
00:03:43,150 --> 00:03:44,979
this would be a very straightforward exercise
97
00:03:44,980 --> 00:03:45,730
to complete.
98
00:03:46,090 --> 00:03:47,910
So, why is it so hard in Rust?
99
00:03:49,240 --> 00:03:51,319
This code seems difficult to write in Rust because
100
00:03:51,320 --> 00:03:52,569
ownership is a different paradigm
101
00:03:52,570 --> 00:03:55,040
than we are used to from other languages.
102
00:03:56,250 --> 00:03:58,099
Rust has performance as a primary
103
00:03:58,100 --> 00:04:00,169
goal, which rules out having a garbage
104
00:04:00,170 --> 00:04:02,620
collector as found in many high-level languages,
105
00:04:02,660 --> 00:04:04,540
as we discussed in the previous module.
106
00:04:05,060 --> 00:04:06,949
However, manual memory management,
107
00:04:06,950 --> 00:04:09,100
as found in C, is too error-prone.
108
00:04:09,470 --> 00:04:10,930
What else is left?
109
00:04:12,420 --> 00:04:14,429
Rust takes a third approach, different from most
110
00:04:14,430 --> 00:04:15,239
other languages,
111
00:04:15,240 --> 00:04:17,450
and helps you manage memory using ownership,
112
00:04:17,610 --> 00:04:19,439
which prevents bugs by cleaning up when
113
00:04:19,440 --> 00:04:20,620
the owner goes out of scope.
114
00:04:21,040 --> 00:04:23,090
Rust makes you conscious of performance
115
00:04:23,100 --> 00:04:25,109
by making slow operations, like cloning,
116
00:04:25,110 --> 00:04:25,850
explicit.
117
00:04:27,360 --> 00:04:29,189
Working within the system of ownership
118
00:04:29,190 --> 00:04:31,130
can feel different than what you're used to.
119
00:04:31,530 --> 00:04:33,389
The benefit of working within the ownership
120
00:04:33,390 --> 00:04:35,309
system is that you get control over
121
00:04:35,310 --> 00:04:37,199
performance while still maintaining
122
00:04:37,200 --> 00:04:39,410
memory safety and avoiding errors.
123
00:04:40,780 --> 00:04:43,029
The good news is that, as you get more experience
124
00:04:43,030 --> 00:04:45,219
working with ownership, it will get easier
125
00:04:45,220 --> 00:04:47,319
and easier to think in the way that Rust works
126
00:04:47,320 --> 00:04:48,920
and code with the grain.
127
00:04:50,360 --> 00:04:52,219
So, will all of our code have calls to
128
00:04:52,220 --> 00:04:53,800
.clone() scattered everywhere?
129
00:04:54,080 --> 00:04:56,149
Probably not. The working solution
130
00:04:56,150 --> 00:04:58,249
we showed for this example actually isn't
131
00:04:58,250 --> 00:05:00,169
idiomatic Rust. What
132
00:05:00,170 --> 00:05:02,089
is idiomatic uses a feature of Rust
133
00:05:02,090 --> 00:05:04,009
called borrowing. The next
134
00:05:04,010 --> 00:05:05,899
module will introduce and explain
135
00:05:05,900 --> 00:05:08,269
how we can use borrowing to make this solution
136
00:05:08,270 --> 00:05:10,720
less annoying, less verbose,
137
00:05:10,890 --> 00:05:12,040
and more efficient.
138
00:05:13,420 --> 00:05:15,329
To sum up this module, we looked
139
00:05:15,330 --> 00:05:17,199
at one way of solving an exercise
140
00:05:17,200 --> 00:05:18,129
involving strings
141
00:05:18,130 --> 00:05:20,049
and functions using cloning to move
142
00:05:20,050 --> 00:05:21,909
data into a function without giving
143
00:05:21,910 --> 00:05:22,740
up ownership.
144
00:05:23,380 --> 00:05:25,530
We looked at some solutions that didn't work
145
00:05:25,660 --> 00:05:26,889
because the data wasn't cloned
146
00:05:26,890 --> 00:05:28,370
or moved in the right way.
147
00:05:29,400 --> 00:05:31,259
We talked about why this feels difficult in
148
00:05:31,260 --> 00:05:33,509
Rust because of Rust's memory management
149
00:05:33,510 --> 00:05:34,910
and ownership features.
150
00:05:35,580 --> 00:05:38,220
Now, we're ready to talk all about borrowing.