1
00:00:05,220 --> 00:00:07,049
Let's get started! In the rest of this
2
00:00:07,050 --> 00:00:09,530
module, we're going to cover what ownership means.
3
00:00:09,690 --> 00:00:11,909
We'll talk about how Rust's system of ownership
4
00:00:11,910 --> 00:00:13,829
differs from some other languages, such
5
00:00:13,830 --> 00:00:15,609
as manual memory management in C
6
00:00:15,610 --> 00:00:17,180
and garbage collection in Ruby.
7
00:00:18,440 --> 00:00:19,619
Then, we'll get into some code
8
00:00:19,620 --> 00:00:21,629
with the String data type. We'll show
9
00:00:21,630 --> 00:00:23,759
how you can move ownership from one function
10
00:00:23,760 --> 00:00:25,629
to another, and how you can clone data
11
00:00:25,630 --> 00:00:26,659
to duplicate it
12
00:00:26,660 --> 00:00:28,700
and, thus, have two separate owners.
13
00:00:30,100 --> 00:00:32,079
We'll finish up by giving you an exercise
14
00:00:32,080 --> 00:00:33,969
to try on your own before you watch the
15
00:00:33,970 --> 00:00:36,189
next module, in which we'll discuss possible
16
00:00:36,190 --> 00:00:37,790
solutions to the exercise.
17
00:00:39,130 --> 00:00:41,160
So, what is ownership?
18
00:00:42,480 --> 00:00:44,339
Ownership is Rust's strategy
19
00:00:44,340 --> 00:00:45,869
for managing data and memory
20
00:00:45,870 --> 00:00:47,490
and preventing common problems.
21
00:00:48,870 --> 00:00:51,179
Every chunk of memory must have one variable
22
00:00:51,180 --> 00:00:52,570
that is the memory's owner.
23
00:00:52,860 --> 00:00:54,989
The owner is responsible for cleaning up
24
00:00:54,990 --> 00:00:57,350
or deallocating that chunk of memory.
25
00:00:58,020 --> 00:00:59,849
This cleanup happens automatically when
26
00:00:59,850 --> 00:01:01,820
the owner variable goes out of scope.
27
00:01:03,120 --> 00:01:05,639
The owner of data is also who is responsible
28
00:01:05,640 --> 00:01:07,919
for deciding whether that data is mutable
29
00:01:07,920 --> 00:01:08,590
or not.
30
00:01:10,160 --> 00:01:12,029
Imagine a piece of data as a dish of
31
00:01:12,030 --> 00:01:13,850
food that Jane owns.
32
00:01:14,220 --> 00:01:15,659
She brings it to a party to share
33
00:01:15,660 --> 00:01:17,579
with everyone. As the
34
00:01:17,580 --> 00:01:19,469
owner of the dish, she is responsible for
35
00:01:19,470 --> 00:01:20,969
cleaning up any leftovers
36
00:01:20,970 --> 00:01:21,809
and taking the dish
37
00:01:21,810 --> 00:01:24,220
with her when she leaves at the end of the evening.
38
00:01:25,690 --> 00:01:27,519
One problem that ownership solves
39
00:01:27,520 --> 00:01:29,559
is that leaving the dish around the host's house
40
00:01:29,560 --> 00:01:30,339
would be rude
41
00:01:30,340 --> 00:01:32,439
and mean that the host's house gets more
42
00:01:32,440 --> 00:01:33,519
and more messy
43
00:01:33,520 --> 00:01:35,769
the more parties they have. Eventually,
44
00:01:35,770 --> 00:01:37,130
the house would run out of space to have
45
00:01:37,180 --> 00:01:38,630
any parties in at all.
46
00:01:41,050 --> 00:01:42,369
Cleaning up memory when you're done
47
00:01:42,370 --> 00:01:44,379
with it is important so that your program
48
00:01:44,380 --> 00:01:46,239
doesn't use up more of the system's
49
00:01:46,240 --> 00:01:47,850
space than necessary.
50
00:01:49,150 --> 00:01:51,009
Another problem ownership solves is that
51
00:01:51,010 --> 00:01:52,869
the owner of the dish is responsible for
52
00:01:52,870 --> 00:01:55,200
cleaning it up, not anyone else.
53
00:01:55,660 --> 00:01:57,729
If the hosts decide to clean up the dish while people
54
00:01:57,730 --> 00:01:59,109
at the party were still eating,
55
00:01:59,110 --> 00:02:00,150
that would be rude.
56
00:02:00,310 --> 00:02:02,139
You'd go to scoop another serving of the dish
57
00:02:02,140 --> 00:02:03,330
and nothing would be there.
58
00:02:03,640 --> 00:02:05,769
That's like one part of the program cleaning up memory
59
00:02:05,770 --> 00:02:07,860
before another part is done using it.
60
00:02:09,169 --> 00:02:10,249
Let's contrast this
61
00:02:10,250 --> 00:02:11,920
with what other languages do.
62
00:02:12,710 --> 00:02:14,779
We're going to look at C, which does manual memory
63
00:02:14,780 --> 00:02:16,909
management, and Ruby, which has a garbage
64
00:02:16,910 --> 00:02:17,650
collector.
65
00:02:19,100 --> 00:02:21,199
In C, your code has to explicitly
66
00:02:21,200 --> 00:02:22,909
perform both allocation
67
00:02:22,910 --> 00:02:24,250
and deallocation.
68
00:02:24,770 --> 00:02:26,600
When you want space to store some data,
69
00:02:26,750 --> 00:02:27,599
you call malloc
70
00:02:27,600 --> 00:02:29,680
and specify the amount of memory you want.
71
00:02:30,170 --> 00:02:32,359
When you're done with that space, you call free
72
00:02:32,360 --> 00:02:34,420
to return the memory to the operating system.
73
00:02:35,500 --> 00:02:37,809
The advantage of this is that you have complete control
74
00:02:37,810 --> 00:02:39,549
over when your program allocates memory
75
00:02:39,550 --> 00:02:40,980
and how much it uses.
76
00:02:41,400 --> 00:02:43,239
This control lets you write programs that run
77
00:02:43,240 --> 00:02:45,790
quickly and take up the least amount of space.
78
00:02:47,150 --> 00:02:49,129
However, having complete control is
79
00:02:49,130 --> 00:02:50,620
also a disadvantage.
80
00:02:50,680 --> 00:02:52,549
C, by itself, doesn't prevent you from
81
00:02:52,550 --> 00:02:53,590
messing this up.
82
00:02:53,990 --> 00:02:56,059
If one part of your program calls free
83
00:02:56,060 --> 00:02:58,009
and then other part tries to use that memory
84
00:02:58,010 --> 00:02:59,959
again, that's called a "use after
85
00:02:59,960 --> 00:03:00,620
free"
86
00:03:00,800 --> 00:03:02,679
problem, and is like the host of the party cleaning
87
00:03:02,680 --> 00:03:04,780
up a dish while people are still eating from it.
88
00:03:05,360 --> 00:03:07,189
If you forget to call free once you're done with
89
00:03:07,190 --> 00:03:07,900
the memory,
90
00:03:08,000 --> 00:03:09,790
eventually you'll run out of space.
91
00:03:10,130 --> 00:03:11,209
This is a memory leak,
92
00:03:11,210 --> 00:03:13,279
and it's like bringing a dish over to someone's house
93
00:03:13,280 --> 00:03:14,540
and never cleaning it up.
94
00:03:15,760 --> 00:03:17,649
If two parts of your program try to clean up the
95
00:03:17,650 --> 00:03:19,569
same data, that's known as a "double
96
00:03:19,570 --> 00:03:21,549
free" problem and can cause memory
97
00:03:21,550 --> 00:03:22,340
corruption.
98
00:03:23,190 --> 00:03:25,019
This would be like the owner of a dish and the
99
00:03:25,020 --> 00:03:26,939
host both trying to clean up the same
100
00:03:26,940 --> 00:03:27,620
dish.
101
00:03:29,000 --> 00:03:30,709
There are tools to help diagnose
102
00:03:30,710 --> 00:03:32,449
and debug these memory problems,
103
00:03:32,450 --> 00:03:34,369
but the C language doesn't help us out very
104
00:03:34,370 --> 00:03:35,140
much.
105
00:03:35,510 --> 00:03:37,459
These problems happen a lot and have caused
106
00:03:37,460 --> 00:03:39,469
major security flaws and crashes
107
00:03:39,470 --> 00:03:41,320
in lots of different kinds of software.
108
00:03:41,870 --> 00:03:43,849
Just trying really hard to be careful
109
00:03:43,850 --> 00:03:46,159
hasn't proven to be a very robust strategy
110
00:03:46,160 --> 00:03:47,730
for software as a whole.
111
00:03:49,080 --> 00:03:50,939
Ruby, on the other hand, takes care of
112
00:03:50,940 --> 00:03:52,580
managing memory for you,
113
00:03:52,590 --> 00:03:54,539
and has a component called the garbage collector
114
00:03:54,540 --> 00:03:56,429
that runs alongside your program cleaning up
115
00:03:56,430 --> 00:03:57,740
memory that you're done with.
116
00:03:58,620 --> 00:04:00,519
The advantage of a garbage collector is that, while
117
00:04:00,520 --> 00:04:02,529
you're writing code, you don't really have to think
118
00:04:02,530 --> 00:04:04,050
about managing memory at all.
119
00:04:04,300 --> 00:04:06,189
The garbage collector keeps track of which memory
120
00:04:06,190 --> 00:04:07,059
is still in use,
121
00:04:07,060 --> 00:04:08,879
and cleans up any data that your program is done with.
122
00:04:08,880 --> 00:04:10,869
You also can't have
123
00:04:10,870 --> 00:04:12,819
any other problems we mentioned with C because
124
00:04:12,820 --> 00:04:14,960
Ruby is taking care of all that for you.
125
00:04:16,350 --> 00:04:18,179
The downside of using a garbage collector
126
00:04:18,180 --> 00:04:20,690
is that you lose control and performance.
127
00:04:20,940 --> 00:04:22,829
When it runs, the garbage collector takes up
128
00:04:22,830 --> 00:04:24,809
computing resources that your program
129
00:04:24,810 --> 00:04:26,909
could be using. Your program will
130
00:04:26,910 --> 00:04:28,739
also likely use more memory than
131
00:04:28,740 --> 00:04:30,779
it strictly needs because the garbage collector
132
00:04:30,780 --> 00:04:32,669
only cleans up memory when it's sure you're done
133
00:04:32,670 --> 00:04:33,220
with it.
134
00:04:34,560 --> 00:04:36,669
Rust is trying to get the best of both worlds
135
00:04:36,670 --> 00:04:38,739
here. Ownership gives you control
136
00:04:38,740 --> 00:04:40,119
over memory allocation
137
00:04:40,120 --> 00:04:41,820
and the associated performance,
138
00:04:41,830 --> 00:04:43,719
but by cleaning up data automatically
139
00:04:43,720 --> 00:04:45,090
when the owner goes out of scope,
140
00:04:45,280 --> 00:04:47,059
we can't mess up the memory access
141
00:04:47,060 --> 00:04:48,879
and we won't be using memory longer
142
00:04:48,880 --> 00:04:50,070
than we strictly need to.
143
00:04:51,600 --> 00:04:52,499
Let's get concrete
144
00:04:52,500 --> 00:04:54,710
with ownership by using strings.
145
00:04:55,080 --> 00:04:56,909
A String is a type that has data
146
00:04:56,910 --> 00:04:59,210
that needs to be cleaned up when it goes out of scope.
147
00:05:00,540 --> 00:05:02,619
A String value tracks how much space
148
00:05:02,620 --> 00:05:04,779
is allocated, how much of that space
149
00:05:04,780 --> 00:05:05,790
is used,
150
00:05:06,350 --> 00:05:08,270
and the UTF-8 data.
151
00:05:08,830 --> 00:05:10,689
When the owner of the string value goes out
152
00:05:10,690 --> 00:05:12,619
of scope, the UTF-8 data
153
00:05:12,620 --> 00:05:14,100
needs to be cleaned up.
154
00:05:15,380 --> 00:05:17,590
There are a bunch of ways to create a string.
155
00:05:17,660 --> 00:05:19,460
One is by using String::from.
156
00:05:19,760 --> 00:05:21,799
This code create a new variable, named
157
00:05:21,800 --> 00:05:23,659
a, and sets it to a new string
158
00:05:23,660 --> 00:05:25,579
instance by allocating memory, which
159
00:05:25,580 --> 00:05:27,180
holds the text hello.
160
00:05:27,710 --> 00:05:29,539
We can use the a variable, such
161
00:05:29,540 --> 00:05:31,819
as by printing it out, until the closing
162
00:05:31,820 --> 00:05:33,820
curly bracket of the main function.
163
00:05:34,190 --> 00:05:36,019
At that point, a goes out
164
00:05:36,020 --> 00:05:37,969
of scope and the data allocated for
165
00:05:37,970 --> 00:05:39,470
the string gets cleaned up.
166
00:05:40,820 --> 00:05:42,919
We can modify the String data by adding
167
00:05:42,920 --> 00:05:44,610
more text to the String.
168
00:05:45,050 --> 00:05:46,870
The variable needs to be made mutable,
169
00:05:46,970 --> 00:05:48,859
and then we can call the push_str
170
00:05:48,860 --> 00:05:49,909
method on a
171
00:05:49,910 --> 00:05:51,370
and give it more text.
172
00:05:51,890 --> 00:05:53,809
This will allocate more memory, if
173
00:05:53,810 --> 00:05:54,760
necessary,
174
00:05:54,940 --> 00:05:56,779
and when we go to use a, it will have
175
00:05:56,780 --> 00:05:58,160
hello there! in it.
176
00:05:59,470 --> 00:06:01,749
By default, with non-primitive types,
177
00:06:01,750 --> 00:06:03,210
Rust moves ownership.
178
00:06:04,540 --> 00:06:07,050
If we have the variable, s, holding a String, and
179
00:06:07,290 --> 00:06:09,189
we create a new variable, t, and
180
00:06:09,190 --> 00:06:11,330
assign s to t,
181
00:06:11,650 --> 00:06:13,629
this will move ownership of the String from
182
00:06:13,630 --> 00:06:14,630
s to t.
183
00:06:15,190 --> 00:06:17,139
Afterwards, the variable, s, is no
184
00:06:17,140 --> 00:06:18,980
longer available to be used.
185
00:06:20,500 --> 00:06:22,599
We've shown moving ownership in the context
186
00:06:22,600 --> 00:06:23,580
of variables.
187
00:06:23,710 --> 00:06:25,599
Now, let's bring functions into the mix
188
00:06:25,600 --> 00:06:27,429
and see how moving also applies to
189
00:06:27,430 --> 00:06:28,080
them.
190
00:06:28,340 --> 00:06:30,189
Here's a function named say
191
00:06:30,190 --> 00:06:31,749
that takes a string as a parameter
192
00:06:31,750 --> 00:06:32,810
and prints it out.
193
00:06:33,310 --> 00:06:35,379
This is different from the previous example,
194
00:06:35,380 --> 00:06:37,200
where we did this in the main function.
195
00:06:37,750 --> 00:06:39,159
When we call the say function
196
00:06:39,160 --> 00:06:40,890
with a as the argument,
197
00:06:41,230 --> 00:06:43,509
ownership is transferred from a
198
00:06:43,510 --> 00:06:44,549
to s,
199
00:06:44,550 --> 00:06:46,419
and the string data gets cleaned up at the
200
00:06:46,420 --> 00:06:48,390
end of the say function.
201
00:06:49,830 --> 00:06:51,779
We can verify this by trying to use
202
00:06:51,780 --> 00:06:53,729
a again after calling
203
00:06:53,730 --> 00:06:55,060
say in main.
204
00:06:55,260 --> 00:06:57,050
Here, we try to print it out.
205
00:06:58,480 --> 00:07:00,409
If we try to compile this code, we'll get
206
00:07:00,410 --> 00:07:02,679
an error that we're not allowed to use a
207
00:07:02,680 --> 00:07:04,530
because it's been moved into say.
208
00:07:05,970 --> 00:07:07,859
We can also transfer ownership out of
209
00:07:07,860 --> 00:07:09,770
a function by returning a value.
210
00:07:09,920 --> 00:07:11,759
Here's a function that doesn't take any
211
00:07:11,760 --> 00:07:13,589
parameters but returns ownership of a
212
00:07:13,590 --> 00:07:15,639
string that contains the heart eyes
213
00:07:15,640 --> 00:07:16,790
cat emoji.
214
00:07:17,350 --> 00:07:19,469
Memory is allocated in the heart_eyes_cat
215
00:07:19,470 --> 00:07:21,740
function, but it isn't cleaned up there.
216
00:07:22,140 --> 00:07:24,089
Ownership of the memory is transferred to
217
00:07:24,090 --> 00:07:25,989
a, and the memory is cleaned up
218
00:07:25,990 --> 00:07:27,839
at the end of main when a goes
219
00:07:27,840 --> 00:07:28,590
out of scope.
220
00:07:30,040 --> 00:07:32,319
What if we wanted to keep ownership of some data,
221
00:07:32,320 --> 00:07:34,209
but needed to also give ownership of
222
00:07:34,210 --> 00:07:36,150
the data to another piece of code?
223
00:07:36,520 --> 00:07:37,920
We can do that by cloning.
224
00:07:39,250 --> 00:07:41,529
Cloning makes a deep copy of the allocated
225
00:07:41,530 --> 00:07:42,220
memory.
226
00:07:42,550 --> 00:07:44,479
Then there will be two copies of the data that
227
00:07:44,480 --> 00:07:45,570
each have an owner,
228
00:07:45,670 --> 00:07:47,709
and each owner is responsible for cleaning
229
00:07:47,710 --> 00:07:48,690
up their data.
230
00:07:50,180 --> 00:07:52,069
Cloning is one way to get around errors
231
00:07:52,070 --> 00:07:54,220
having to do with moved values.
232
00:07:54,440 --> 00:07:56,329
You may end up allocating more memory
233
00:07:56,330 --> 00:07:57,690
than you strictly need to,
234
00:07:57,800 --> 00:07:59,950
but you'll be allowed to do what you're trying to do.
235
00:08:00,740 --> 00:08:02,809
As an example, when we wanted to use
236
00:08:02,810 --> 00:08:04,879
a again, after transferring ownership
237
00:08:04,880 --> 00:08:06,100
to the say function,
238
00:08:06,290 --> 00:08:08,229
we can call clone on a
239
00:08:08,230 --> 00:08:10,069
and transfer ownership of the clone
240
00:08:10,070 --> 00:08:11,139
to the say function
241
00:08:11,140 --> 00:08:11,770
instead.
242
00:08:14,030 --> 00:08:16,039
This code compiles and runs. The cloned data gets
243
00:08:16,040 --> 00:08:17,920
cleaned up at the end of say,
244
00:08:17,960 --> 00:08:19,789
and the original data gets cleaned up
245
00:08:19,790 --> 00:08:21,070
at the end of main.
246
00:08:22,430 --> 00:08:23,959
It's time for you to get some experience
247
00:08:23,960 --> 00:08:25,849
with strings, ownership,
248
00:08:25,850 --> 00:08:27,469
moving, and cloning
249
00:08:27,470 --> 00:08:29,200
by trying this exercise.
250
00:08:30,700 --> 00:08:32,529
Your task is to implement a function
251
00:08:32,530 --> 00:08:34,928
that turns words into their plural versions
252
00:08:34,929 --> 00:08:37,350
by adding an s to the end of the word.
253
00:08:38,320 --> 00:08:39,099
In main,
254
00:08:39,100 --> 00:08:40,979
you'll have a string like book,
255
00:08:41,080 --> 00:08:43,439
and your goal is to get main to print
256
00:08:43,630 --> 00:08:44,910
I have one book,
257
00:08:45,040 --> 00:08:47,109
you have two books, by calling
258
00:08:47,110 --> 00:08:48,540
your pluralize function.
259
00:08:50,210 --> 00:08:52,129
Note that the String type has a method
260
00:08:52,130 --> 00:08:53,959
called push_str that you might
261
00:08:53,960 --> 00:08:55,060
find useful.
262
00:08:55,310 --> 00:08:57,349
It's not the only way to complete this exercise,
263
00:08:57,350 --> 00:08:57,910
though.
264
00:08:59,600 --> 00:09:01,459
If you get compiler errors while working on
265
00:09:01,460 --> 00:09:03,379
this, or if you get stuck, that's
266
00:09:03,380 --> 00:09:05,740
great! In the next module,
267
00:09:05,750 --> 00:09:07,729
we'll be going through some of the problems you might
268
00:09:07,730 --> 00:09:10,110
run into while working on this exercise.
269
00:09:11,500 --> 00:09:13,719
Now you've learned how Rust's ownership
270
00:09:13,720 --> 00:09:15,990
differs from manual memory management
271
00:09:16,000 --> 00:09:18,249
and garbage collection, as well as the basics
272
00:09:18,250 --> 00:09:19,290
about String.
273
00:09:19,630 --> 00:09:21,409
Apply what you've learned about moving
274
00:09:21,410 --> 00:09:23,799
and cloning as you try the exercise
275
00:09:23,800 --> 00:09:25,200
before the next module.