]> git.proxmox.com Git - rustc.git/blob - src/doc/book/nostarch/chapter15.md
New upstream version 1.64.0+dfsg1
[rustc.git] / src / doc / book / nostarch / chapter15.md
1 <!-- DO NOT EDIT THIS FILE.
2
3 This file is periodically generated from the content in the `/src/`
4 directory, so all fixes need to be made in `/src/`.
5 -->
6
7 [TOC]
8
9 # Smart Pointers
10
11 A *pointer* is a general concept for a variable that contains an address in
12 memory. This address refers to, or “points at,” some other data. The most
13 common kind of pointer in Rust is a reference, which you learned about in
14 Chapter 4. References are indicated by the `&` symbol and borrow the value they
15 point to. They don’t have any special capabilities other than referring to
16 data, and have no overhead.
17
18 *Smart pointers*, on the other hand, are data structures that act like a
19 pointer but also have additional metadata and capabilities. The concept of
20 smart pointers isn’t unique to Rust: smart pointers originated in C++ and exist
21 in other languages as well. Rust has a variety of smart pointers defined in the
22 standard library that provide functionality beyond that provided by references.
23 To explore the general concept, we'll look at a couple of different examples of
24 smart pointers, including a *reference counting* smart pointer type. This
25 pointer enables you to allow data to have multiple owners by keeping track of
26 the number of owners and, when no owners remain, cleaning up the data.
27
28 Rust, with its concept of ownership and borrowing, has an additional difference
29 between references and smart pointers: while references only borrow data, in
30 many cases, smart pointers *own* the data they point to.
31
32 Though we didn't call them as such at the time, we’ve already encountered a few
33 smart pointers in this book, including `String` and `Vec<T>` in Chapter 8. Both
34 these types count as smart pointers because they own some memory and allow you
35 to manipulate it. They also have metadata and extra capabilities or guarantees.
36 `String`, for example, stores its capacity as metadata and has the extra
37 ability to ensure its data will always be valid UTF-8.
38
39 Smart pointers are usually implemented using structs. Unlike an ordinary
40 struct, smart pointers implement the `Deref` and `Drop` traits. The `Deref`
41 trait allows an instance of the smart pointer struct to behave like a reference
42 so you can write your code to work with either references or smart pointers.
43 The `Drop` trait allows you to customize the code that's run when an instance
44 of the smart pointer goes out of scope. In this chapter, we’ll discuss both
45 traits and demonstrate why they’re important to smart pointers.
46
47 Given that the smart pointer pattern is a general design pattern used
48 frequently in Rust, this chapter won’t cover every existing smart pointer. Many
49 libraries have their own smart pointers, and you can even write your own. We’ll
50 cover the most common smart pointers in the standard library:
51
52 * `Box<T>` for allocating values on the heap
53 * `Rc<T>`, a reference counting type that enables multiple ownership
54 * `Ref<T>` and `RefMut<T>`, accessed through `RefCell<T>`, a type that enforces
55 the borrowing rules at runtime instead of compile time
56
57 In addition, we’ll cover the *interior mutability* pattern where an immutable
58 type exposes an API for mutating an interior value. We’ll also discuss
59 *reference cycles*: how they can leak memory and how to prevent them.
60
61 Let’s dive in!
62
63 ## Using `Box<T>` to Point to Data on the Heap
64
65 The most straightforward smart pointer is a *box*, whose type is written
66 `Box<T>`. Boxes allow you to store data on the heap rather than the stack. What
67 remains on the stack is the pointer to the heap data. Refer to Chapter 4 to
68 review the difference between the stack and the heap.
69
70 Boxes don’t have performance overhead, other than storing their data on the
71 heap instead of on the stack. But they don’t have many extra capabilities
72 either. You’ll use them most often in these situations:
73
74 * When you have a type whose size can’t be known at compile time and you want
75 to use a value of that type in a context that requires an exact size
76 * When you have a large amount of data and you want to transfer ownership but
77 ensure the data won’t be copied when you do so
78 * When you want to own a value and you care only that it’s a type that
79 implements a particular trait rather than being of a specific type
80
81 We’ll demonstrate the first situation in the “Enabling Recursive Types with
82 Boxes” section. In the second case, transferring ownership of a large amount of
83 data can take a long time because the data is copied around on the stack. To
84 improve performance in this situation, we can store the large amount of data on
85 the heap in a box. Then, only the small amount of pointer data is copied around
86 on the stack, while the data it references stays in one place on the heap. The
87 third case is known as a *trait object*, and Chapter 17 devotes an entire
88 section, “Using Trait Objects That Allow for Values of Different Types,” just
89 to that topic. So what you learn here you’ll apply again in Chapter 17!
90
91 ### Using a `Box<T>` to Store Data on the Heap
92
93 Before we discuss the heap storage use case for `Box<T>`, we’ll cover the
94 syntax and how to interact with values stored within a `Box<T>`.
95
96 Listing 15-1 shows how to use a box to store an `i32` value on the heap:
97
98 Filename: src/main.rs
99
100 ```
101 fn main() {
102 let b = Box::new(5);
103 println!("b = {}", b);
104 }
105 ```
106
107 Listing 15-1: Storing an `i32` value on the heap using a box
108
109 We define the variable `b` to have the value of a `Box` that points to the
110 value `5`, which is allocated on the heap. This program will print `b = 5`; in
111 this case, we can access the data in the box similar to how we would if this
112 data were on the stack. Just like any owned value, when a box goes out of
113 scope, as `b` does at the end of `main`, it will be deallocated. The
114 deallocation happens both for the box (stored on the stack) and the data it
115 points to (stored on the heap).
116
117 Putting a single value on the heap isn’t very useful, so you won’t use boxes by
118 themselves in this way very often. Having values like a single `i32` on the
119 stack, where they’re stored by default, is more appropriate in the majority of
120 situations. Let’s look at a case where boxes allow us to define types that we
121 wouldn’t be allowed to if we didn’t have boxes.
122
123 ### Enabling Recursive Types with Boxes
124
125 A value of *recursive type* can have another value of the same type as part of
126 itself. Recursive types pose an issue because at compile time Rust needs to
127 know how much space a type takes up. However, the nesting of values of
128 recursive types could theoretically continue infinitely, so Rust can’t know how
129 much space the value needs. Because boxes have a known size, we can enable
130 recursive types by inserting a box in the recursive type definition.
131
132 As an example of a recursive type, let’s explore the *cons list*. This is a data
133 type commonly found in functional programming languages. The cons list type
134 we’ll define is straightforward except for the recursion; therefore, the
135 concepts in the example we’ll work with will be useful any time you get into
136 more complex situations involving recursive types.
137
138 #### More Information About the Cons List
139
140 A *cons list* is a data structure that comes from the Lisp programming language
141 and its dialects and is made up of nested pairs, and is the Lisp version of a
142 linked list. Its name comes from the `cons` function (short for “construct
143 function”) in Lisp that constructs a new pair from its two arguments. By
144 calling `cons` on a pair consisting of a value and another pair, we can
145 construct cons lists made up of recursive pairs.
146
147 For example, here's a pseudocode representation of a cons list containing the
148 list 1, 2, 3 with each pair in parentheses:
149
150 ```
151 (1, (2, (3, Nil)))
152 ```
153
154 Each item in a cons list contains two elements: the value of the current item
155 and the next item. The last item in the list contains only a value called `Nil`
156 without a next item. A cons list is produced by recursively calling the `cons`
157 function. The canonical name to denote the base case of the recursion is `Nil`.
158 Note that this is not the same as the “null” or “nil” concept in Chapter 6,
159 which is an invalid or absent value.
160
161 The cons list isn’t a commonly used data structure in Rust. Most of the time
162 when you have a list of items in Rust, `Vec<T>` is a better choice to use.
163 Other, more complex recursive data types *are* useful in various situations,
164 but by starting with the cons list in this chapter, we can explore how boxes
165 let us define a recursive data type without much distraction.
166
167 Listing 15-2 contains an enum definition for a cons list. Note that this code
168 won’t compile yet because the `List` type doesn’t have a known size, which
169 we’ll demonstrate.
170
171 Filename: src/main.rs
172
173 ```
174 enum List {
175 Cons(i32, List),
176 Nil,
177 }
178 ```
179
180 Listing 15-2: The first attempt at defining an enum to represent a cons list
181 data structure of `i32` values
182
183 > Note: We’re implementing a cons list that holds only `i32` values for the
184 > purposes of this example. We could have implemented it using generics, as we
185 > discussed in Chapter 10, to define a cons list type that could store values of
186 > any type.
187
188 Using the `List` type to store the list `1, 2, 3` would look like the code in
189 Listing 15-3:
190
191 Filename: src/main.rs
192
193 ```
194 use crate::List::{Cons, Nil};
195
196 fn main() {
197 let list = Cons(1, Cons(2, Cons(3, Nil)));
198 }
199 ```
200
201 Listing 15-3: Using the `List` enum to store the list `1, 2, 3`
202
203 The first `Cons` value holds `1` and another `List` value. This `List` value is
204 another `Cons` value that holds `2` and another `List` value. This `List` value
205 is one more `Cons` value that holds `3` and a `List` value, which is finally
206 `Nil`, the non-recursive variant that signals the end of the list.
207
208 If we try to compile the code in Listing 15-3, we get the error shown in
209 Listing 15-4:
210
211 ```
212 error[E0072]: recursive type `List` has infinite size
213 --> src/main.rs:1:1
214 |
215 1 | enum List {
216 | ^^^^^^^^^ recursive type has infinite size
217 2 | Cons(i32, List),
218 | ---- recursive without indirection
219 |
220 help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` representable
221 ```
222
223 Listing 15-4: The error we get when attempting to define a recursive enum
224
225 The error shows this type “has infinite size.” The reason is that we’ve defined
226 `List` with a variant that is recursive: it holds another value of itself
227 directly. As a result, Rust can’t figure out how much space it needs to store a
228 `List` value. Let’s break down why we get this error. First, we'll look at how
229 Rust decides how much space it needs to store a value of a non-recursive type.
230
231 #### Computing the Size of a Non-Recursive Type
232
233 Recall the `Message` enum we defined in Listing 6-2 when we discussed enum
234 definitions in Chapter 6:
235
236 ```
237 enum Message {
238 Quit,
239 Move { x: i32, y: i32 },
240 Write(String),
241 ChangeColor(i32, i32, i32),
242 }
243 ```
244
245 To determine how much space to allocate for a `Message` value, Rust goes
246 through each of the variants to see which variant needs the most space. Rust
247 sees that `Message::Quit` doesn’t need any space, `Message::Move` needs enough
248 space to store two `i32` values, and so forth. Because only one variant will be
249 used, the most space a `Message` value will need is the space it would take to
250 store the largest of its variants.
251
252 Contrast this with what happens when Rust tries to determine how much space a
253 recursive type like the `List` enum in Listing 15-2 needs. The compiler starts
254 by looking at the `Cons` variant, which holds a value of type `i32` and a value
255 of type `List`. Therefore, `Cons` needs an amount of space equal to the size of
256 an `i32` plus the size of a `List`. To figure out how much memory the `List`
257 type needs, the compiler looks at the variants, starting with the `Cons`
258 variant. The `Cons` variant holds a value of type `i32` and a value of type
259 `List`, and this process continues infinitely, as shown in Figure 15-1.
260
261 <img alt="An infinite Cons list" src="img/trpl15-01.svg" class="center" style="width: 50%;" />
262
263 Figure 15-1: An infinite `List` consisting of infinite `Cons` variants
264
265 #### Using `Box<T>` to Get a Recursive Type with a Known Size
266
267 Because Rust can’t figure out how much space to allocate for recursively
268 defined types, the compiler gives an error with this helpful suggestion:
269
270 ```
271 help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` representable
272 |
273 2 | Cons(i32, Box<List>),
274 | ^^^^ ^
275 ```
276
277 In this suggestion, “indirection” means that instead of storing a value
278 directly, we should change the data structure to store the value indirectly by
279 storing a pointer to the value instead.
280
281 Because a `Box<T>` is a pointer, Rust always knows how much space a `Box<T>`
282 needs: a pointer’s size doesn’t change based on the amount of data it’s
283 pointing to. This means we can put a `Box<T>` inside the `Cons` variant instead
284 of another `List` value directly. The `Box<T>` will point to the next `List`
285 value that will be on the heap rather than inside the `Cons` variant.
286 Conceptually, we still have a list, created with lists holding other lists, but
287 this implementation is now more like placing the items next to one another
288 rather than inside one another.
289
290 We can change the definition of the `List` enum in Listing 15-2 and the usage
291 of the `List` in Listing 15-3 to the code in Listing 15-5, which will compile:
292
293 Filename: src/main.rs
294
295 ```
296 enum List {
297 Cons(i32, Box<List>),
298 Nil,
299 }
300
301 use crate::List::{Cons, Nil};
302
303 fn main() {
304 let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
305 }
306 ```
307
308 Listing 15-5: Definition of `List` that uses `Box<T>` in order to have a known
309 size
310
311 The `Cons` variant needs the size of an `i32` plus the space to store the
312 box’s pointer data. The `Nil` variant stores no values, so it needs less space
313 than the `Cons` variant. We now know that any `List` value will take up the
314 size of an `i32` plus the size of a box’s pointer data. By using a box, we’ve
315 broken the infinite, recursive chain, so the compiler can figure out the size
316 it needs to store a `List` value. Figure 15-2 shows what the `Cons` variant
317 looks like now.
318
319 <img alt="A finite Cons list" src="img/trpl15-02.svg" class="center" />
320
321 Figure 15-2: A `List` that is not infinitely sized because `Cons` holds a `Box`
322
323 Boxes provide only the indirection and heap allocation; they don’t have any
324 other special capabilities, like those we’ll see with the other smart pointer
325 types. They also don’t have the performance overhead that these special
326 capabilities incur, so they can be useful in cases like the cons list where the
327 indirection is the only feature we need. We’ll look at more use cases for boxes
328 in Chapter 17, too.
329
330 The `Box<T>` type is a smart pointer because it implements the `Deref` trait,
331 which allows `Box<T>` values to be treated like references. When a `Box<T>`
332 value goes out of scope, the heap data that the box is pointing to is cleaned
333 up as well because of the `Drop` trait implementation. These two traits will be
334 even more important to the functionality provided by the other smart pointer
335 types we’ll discuss in the rest of this chapter. Let’s explore these two traits
336 in more detail.
337
338 ## Treating Smart Pointers Like Regular References with the `Deref` Trait
339
340 Implementing the `Deref` trait allows you to customize the behavior of the
341 *dereference operator* `*` (not to be confused with the multiplication or glob
342 operator). By implementing `Deref` in such a way that a smart pointer can be
343 treated like a regular reference, you can write code that operates on
344 references and use that code with smart pointers too.
345
346 Let’s first look at how the dereference operator works with regular references.
347 Then we’ll try to define a custom type that behaves like `Box<T>`, and see why
348 the dereference operator doesn’t work like a reference on our newly defined
349 type. We’ll explore how implementing the `Deref` trait makes it possible for
350 smart pointers to work in ways similar to references. Then we’ll look at
351 Rust’s *deref coercion* feature and how it lets us work with either references
352 or smart pointers.
353
354 > Note: there’s one big difference between the `MyBox<T>` type we’re about to
355 > build and the real `Box<T>`: our version will not store its data on the heap.
356 > We are focusing this example on `Deref`, so where the data is actually stored
357 > is less important than the pointer-like behavior.
358
359 ### Following the Pointer to the Value
360
361 A regular reference is a type of pointer, and one way to think of a pointer is
362 as an arrow to a value stored somewhere else. In Listing 15-6, we create a
363 reference to an `i32` value and then use the dereference operator to follow the
364 reference to the value:
365
366 Filename: src/main.rs
367
368 ```
369 fn main() {
370 [1] let x = 5;
371 [2] let y = &x;
372
373 [3] assert_eq!(5, x);
374 [4] assert_eq!(5, *y);
375 }
376 ```
377
378 Listing 15-6: Using the dereference operator to follow a reference to an `i32`
379 value
380
381 The variable `x` holds an `i32` value `5` [1]. We set `y` equal to a reference
382 to `x` [2]. We can assert that `x` is equal to `5` [3]. However, if we want to
383 make an assertion about the value in `y`, we have to use `*y` to follow the
384 reference to the value it’s pointing to (hence *dereference*) so the compiler
385 can compare the actual value [4]. Once we dereference `y`, we have access to
386 the integer value `y` is pointing to that we can compare with `5`.
387
388 If we tried to write `assert_eq!(5, y);` instead, we would get this compilation
389 error:
390
391 ```
392 error[E0277]: can't compare `{integer}` with `&{integer}`
393 --> src/main.rs:6:5
394 |
395 6 | assert_eq!(5, y);
396 | ^^^^^^^^^^^^^^^^ no implementation for `{integer} == &{integer}`
397 |
398 = help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}`
399 ```
400
401 Comparing a number and a reference to a number isn’t allowed because they’re
402 different types. We must use the dereference operator to follow the reference
403 to the value it’s pointing to.
404
405 ### Using `Box<T>` Like a Reference
406
407 We can rewrite the code in Listing 15-6 to use a `Box<T>` instead of a
408 reference; the dereference operator used on the `Box<T>` in Listing 15-7
409 functions in the same way as the dereference operator used on the reference in
410 Listing 15-6:
411
412 Filename: src/main.rs
413
414 ```
415 fn main() {
416 let x = 5;
417 [1] let y = Box::new(x);
418
419 assert_eq!(5, x);
420 [2] assert_eq!(5, *y);
421 }
422 ```
423
424 Listing 15-7: Using the dereference operator on a `Box<i32>`
425
426 The main difference between Listing 15-7 and Listing 15-6 is that here we set
427 `y` to be an instance of a box pointing to a copied value of `x` rather than a
428 reference pointing to the value of `x` [1]. In the last assertion [2], we can
429 use the dereference operator to follow the box’s pointer in the same way that
430 we did when `y` was a reference. Next, we’ll explore what is special about
431 `Box<T>` that enables us to use the dereference operator by defining our own
432 box type.
433
434 ### Defining Our Own Smart Pointer
435
436 Let’s build a smart pointer similar to the `Box<T>` type provided by the
437 standard library to experience how smart pointers behave differently from
438 references by default. Then we’ll look at how to add the ability to use the
439 dereference operator.
440
441 The `Box<T>` type is ultimately defined as a tuple struct with one element, so
442 Listing 15-8 defines a `MyBox<T>` type in the same way. We’ll also define a
443 `new` function to match the `new` function defined on `Box<T>`.
444
445 Filename: src/main.rs
446
447 ```
448 [1] struct MyBox<T>(T);
449
450 impl<T> MyBox<T> {
451 [2] fn new(x: T) -> MyBox<T> {
452 [3] MyBox(x)
453 }
454 }
455 ```
456
457 Listing 15-8: Defining a `MyBox<T>` type
458
459 We define a struct named `MyBox` and declare a generic parameter `T` [1],
460 because we want our type to hold values of any type. The `MyBox` type is a
461 tuple struct with one element of type `T`. The `MyBox::new` function takes one
462 parameter of type `T` [2] and returns a `MyBox` instance that holds the value
463 passed in [3].
464
465 Let’s try adding the `main` function in Listing 15-7 to Listing 15-8 and
466 changing it to use the `MyBox<T>` type we’ve defined instead of `Box<T>`. The
467 code in Listing 15-9 won’t compile because Rust doesn’t know how to dereference
468 `MyBox`.
469
470 Filename: src/main.rs
471
472 ```
473 fn main() {
474 let x = 5;
475 let y = MyBox::new(x);
476
477 assert_eq!(5, x);
478 assert_eq!(5, *y);
479 }
480 ```
481
482 Listing 15-9: Attempting to use `MyBox<T>` in the same way we used references
483 and `Box<T>`
484
485 Here’s the resulting compilation error:
486
487 ```
488 error[E0614]: type `MyBox<{integer}>` cannot be dereferenced
489 --> src/main.rs:14:19
490 |
491 14 | assert_eq!(5, *y);
492 | ^^
493 ```
494
495 Our `MyBox<T>` type can’t be dereferenced because we haven’t implemented that
496 ability on our type. To enable dereferencing with the `*` operator, we
497 implement the `Deref` trait.
498
499 ### Treating a Type Like a Reference by Implementing the `Deref` Trait
500
501 As discussed in the “Implementing a Trait on a Type” section of Chapter 10, to
502 implement a trait, we need to provide implementations for the trait’s required
503 methods. The `Deref` trait, provided by the standard library, requires us to
504 implement one method named `deref` that borrows `self` and returns a reference
505 to the inner data. Listing 15-10 contains an implementation of `Deref` to add
506 to the definition of `MyBox`:
507
508 Filename: src/main.rs
509
510 ```
511 use std::ops::Deref;
512
513 impl<T> Deref for MyBox<T> {
514 [1] type Target = T;
515
516 fn deref(&self) -> &Self::Target {
517 [2] &self.0
518 }
519 }
520 ```
521
522 Listing 15-10: Implementing `Deref` on `MyBox<T>`
523
524 The `type Target = T;` syntax [1] defines an associated type for the `Deref`
525 trait to use. Associated types are a slightly different way of declaring a
526 generic parameter, but you don’t need to worry about them for now; we’ll cover
527 them in more detail in Chapter 19.
528
529 We fill in the body of the `deref` method with `&self.0` so `deref` returns a
530 reference to the value we want to access with the `*` operator [2]; recall from
531 the “Using Tuple Structs without Named Fields to Create Different Types”
532 section of Chapter 5 that `.0` accesses the first value in a tuple struct. The
533 `main` function in Listing 15-9 that calls `*` on the `MyBox<T>` value now
534 compiles, and the assertions pass!
535
536 Without the `Deref` trait, the compiler can only dereference `&` references.
537 The `deref` method gives the compiler the ability to take a value of any type
538 that implements `Deref` and call the `deref` method to get a `&` reference that
539 it knows how to dereference.
540
541 When we entered `*y` in Listing 15-9, behind the scenes Rust actually ran this
542 code:
543
544 ```
545 *(y.deref())
546 ```
547
548 Rust substitutes the `*` operator with a call to the `deref` method and then a
549 plain dereference so we don’t have to think about whether or not we need to
550 call the `deref` method. This Rust feature lets us write code that functions
551 identically whether we have a regular reference or a type that implements
552 `Deref`.
553
554 The reason the `deref` method returns a reference to a value, and that the
555 plain dereference outside the parentheses in `*(y.deref())` is still necessary,
556 is to do with the ownership system. If the `deref` method returned the value
557 directly instead of a reference to the value, the value would be moved out of
558 `self`. We don’t want to take ownership of the inner value inside `MyBox<T>` in
559 this case or in most cases where we use the dereference operator.
560
561 Note that the `*` operator is replaced with a call to the `deref` method and
562 then a call to the `*` operator just once, each time we use a `*` in our code.
563 Because the substitution of the `*` operator does not recurse infinitely, we
564 end up with data of type `i32`, which matches the `5` in `assert_eq!` in
565 Listing 15-9.
566
567 ### Implicit Deref Coercions with Functions and Methods
568
569 *Deref coercion* converts a reference to a type that implements the `Deref`
570 trait into a reference to another type. For example, deref coercion can convert
571 `&String` to `&str` because `String` implements the `Deref` trait such that it
572 returns `&str`. Deref coercion is a convenience Rust performs on arguments to
573 functions and methods, and works only on types that implement the `Deref`
574 trait. It happens automatically when we pass a reference to a particular type’s
575 value as an argument to a function or method that doesn’t match the parameter
576 type in the function or method definition. A sequence of calls to the `deref`
577 method converts the type we provided into the type the parameter needs.
578
579 Deref coercion was added to Rust so that programmers writing function and
580 method calls don’t need to add as many explicit references and dereferences
581 with `&` and `*`. The deref coercion feature also lets us write more code that
582 can work for either references or smart pointers.
583
584 To see deref coercion in action, let’s use the `MyBox<T>` type we defined in
585 Listing 15-8 as well as the implementation of `Deref` that we added in Listing
586 15-10. Listing 15-11 shows the definition of a function that has a string slice
587 parameter:
588
589 Filename: src/main.rs
590
591 ```
592 fn hello(name: &str) {
593 println!("Hello, {name}!");
594 }
595 ```
596
597 Listing 15-11: A `hello` function that has the parameter `name` of type `&str`
598
599 We can call the `hello` function with a string slice as an argument, such as
600 `hello("Rust");` for example. Deref coercion makes it possible to call `hello`
601 with a reference to a value of type `MyBox<String>`, as shown in Listing 15-12:
602
603 Filename: src/main.rs
604
605 ```
606 fn main() {
607 let m = MyBox::new(String::from("Rust"));
608 hello(&m);
609 }
610 ```
611
612 Listing 15-12: Calling `hello` with a reference to a `MyBox<String>` value,
613 which works because of deref coercion
614
615 Here we’re calling the `hello` function with the argument `&m`, which is a
616 reference to a `MyBox<String>` value. Because we implemented the `Deref` trait
617 on `MyBox<T>` in Listing 15-10, Rust can turn `&MyBox<String>` into `&String`
618 by calling `deref`. The standard library provides an implementation of `Deref`
619 on `String` that returns a string slice, and this is in the API documentation
620 for `Deref`. Rust calls `deref` again to turn the `&String` into `&str`, which
621 matches the `hello` function’s definition.
622
623 If Rust didn’t implement deref coercion, we would have to write the code in
624 Listing 15-13 instead of the code in Listing 15-12 to call `hello` with a value
625 of type `&MyBox<String>`.
626
627 Filename: src/main.rs
628
629 ```
630 fn main() {
631 let m = MyBox::new(String::from("Rust"));
632 hello(&(*m)[..]);
633 }
634 ```
635
636 Listing 15-13: The code we would have to write if Rust didn’t have deref
637 coercion
638
639 The `(*m)` dereferences the `MyBox<String>` into a `String`. Then the `&` and
640 `[..]` take a string slice of the `String` that is equal to the whole string to
641 match the signature of `hello`. This code without deref coercions is harder to
642 read, write, and understand with all of these symbols involved. Deref coercion
643 allows Rust to handle these conversions for us automatically.
644
645 When the `Deref` trait is defined for the types involved, Rust will analyze the
646 types and use `Deref::deref` as many times as necessary to get a reference to
647 match the parameter’s type. The number of times that `Deref::deref` needs to be
648 inserted is resolved at compile time, so there is no runtime penalty for taking
649 advantage of deref coercion!
650
651 ### How Deref Coercion Interacts with Mutability
652
653 Similar to how you use the `Deref` trait to override the `*` operator on
654 immutable references, you can use the `DerefMut` trait to override the `*`
655 operator on mutable references.
656
657 Rust does deref coercion when it finds types and trait implementations in three
658 cases:
659
660 * From `&T` to `&U` when `T: Deref<Target=U>`
661 * From `&mut T` to `&mut U` when `T: DerefMut<Target=U>`
662 * From `&mut T` to `&U` when `T: Deref<Target=U>`
663
664 The first two cases are the same as each other except that the second
665 implements mutability. The first case states that if you have a `&T`, and `T`
666 implements `Deref` to some type `U`, you can get a `&U` transparently. The
667 second case states that the same deref coercion happens for mutable references.
668
669 The third case is trickier: Rust will also coerce a mutable reference to an
670 immutable one. But the reverse is *not* possible: immutable references will
671 never coerce to mutable references. Because of the borrowing rules, if you have
672 a mutable reference, that mutable reference must be the only reference to that
673 data (otherwise, the program wouldn’t compile). Converting one mutable
674 reference to one immutable reference will never break the borrowing rules.
675 Converting an immutable reference to a mutable reference would require that the
676 initial immutable reference is the only immutable reference to that data, but
677 the borrowing rules don’t guarantee that. Therefore, Rust can’t make the
678 assumption that converting an immutable reference to a mutable reference is
679 possible.
680
681 ## Running Code on Cleanup with the `Drop` Trait
682
683 The second trait important to the smart pointer pattern is `Drop`, which lets
684 you customize what happens when a value is about to go out of scope. You can
685 provide an implementation for the `Drop` trait on any type, and that code
686 can be used to release resources like files or network connections.
687
688 We’re introducing `Drop` in the context of smart pointers because the
689 functionality of the `Drop` trait is almost always used when implementing a
690 smart pointer. For example, when a `Box<T>` is dropped it will deallocate the
691 space on the heap that the box points to.
692
693 In some languages, for some types, the programmer must call code to free memory
694 or resources every time they finish using an instance of those types. Examples
695 include file handles, sockets, or locks. If they forget, the system might
696 become overloaded and crash. In Rust, you can specify that a particular bit of
697 code be run whenever a value goes out of scope, and the compiler will insert
698 this code automatically. As a result, you don’t need to be careful about
699 placing cleanup code everywhere in a program that an instance of a particular
700 type is finished with—you still won’t leak resources!
701
702 You specify the code to run when a value goes out of scope by implementing the
703 `Drop` trait. The `Drop` trait requires you to implement one method named
704 `drop` that takes a mutable reference to `self`. To see when Rust calls `drop`,
705 let’s implement `drop` with `println!` statements for now.
706
707 Listing 15-14 shows a `CustomSmartPointer` struct whose only custom
708 functionality is that it will print `Dropping CustomSmartPointer!` when the
709 instance goes out of scope, to show when Rust runs the `drop` function.
710
711 Filename: src/main.rs
712
713 ```
714 struct CustomSmartPointer {
715 data: String,
716 }
717
718 [1] impl Drop for CustomSmartPointer {
719 fn drop(&mut self) {
720 [2] println!("Dropping CustomSmartPointer with data `{}`!", self.data);
721 }
722 }
723
724 fn main() {
725 [3] let c = CustomSmartPointer {
726 data: String::from("my stuff"),
727 };
728 [4] let d = CustomSmartPointer {
729 data: String::from("other stuff"),
730 };
731 [5] println!("CustomSmartPointers created.");
732 [6] }
733 ```
734
735 Listing 15-14: A `CustomSmartPointer` struct that implements the `Drop` trait
736 where we would put our cleanup code
737
738 The `Drop` trait is included in the prelude, so we don’t need to bring it into
739 scope. We implement the `Drop` trait on `CustomSmartPointer` [1] and provide an
740 implementation for the `drop` method that calls `println!` [2]. The body of the
741 `drop` function is where you would place any logic that you wanted to run when
742 an instance of your type goes out of scope. We’re printing some text here to
743 demonstrate visually when Rust will call `drop`.
744
745 In `main`, we create two instances of `CustomSmartPointer` [3][4] and then
746 print `CustomSmartPointers created` [5]. At the end of `main` [6], our
747 instances of `CustomSmartPointer` will go out of scope, and Rust will call the
748 code we put in the `drop` method [2], printing our final message. Note that we
749 didn’t need to call the `drop` method explicitly.
750
751 When we run this program, we’ll see the following output:
752
753 ```
754 CustomSmartPointers created.
755 Dropping CustomSmartPointer with data `other stuff`!
756 Dropping CustomSmartPointer with data `my stuff`!
757 ```
758
759 Rust automatically called `drop` for us when our instances went out of scope,
760 calling the code we specified. Variables are dropped in the reverse order of
761 their creation, so `d` was dropped before `c`. This example's purpose is to
762 give you a visual guide to how the `drop` method works; usually you would
763 specify the cleanup code that your type needs to run rather than a print
764 message.
765
766 ### Dropping a Value Early with `std::mem::drop`
767
768 Unfortunately, it’s not straightforward to disable the automatic `drop`
769 functionality. Disabling `drop` isn’t usually necessary; the whole point of the
770 `Drop` trait is that it’s taken care of automatically. Occasionally, however,
771 you might want to clean up a value early. One example is when using smart
772 pointers that manage locks: you might want to force the `drop` method that
773 releases the lock so that other code in the same scope can acquire the lock.
774 Rust doesn’t let you call the `Drop` trait’s `drop` method manually; instead
775 you have to call the `std::mem::drop` function provided by the standard library
776 if you want to force a value to be dropped before the end of its scope.
777
778 If we try to call the `Drop` trait’s `drop` method manually by modifying the
779 `main` function from Listing 15-14, as shown in Listing 15-15, we’ll get a
780 compiler error:
781
782 Filename: src/main.rs
783
784 ```
785 fn main() {
786 let c = CustomSmartPointer {
787 data: String::from("some data"),
788 };
789 println!("CustomSmartPointer created.");
790 c.drop();
791 println!("CustomSmartPointer dropped before the end of main.");
792 }
793 ```
794
795 Listing 15-15: Attempting to call the `drop` method from the `Drop` trait
796 manually to clean up early
797
798 When we try to compile this code, we’ll get this error:
799
800 ```
801 error[E0040]: explicit use of destructor method
802 --> src/main.rs:16:7
803 |
804 16 | c.drop();
805 | --^^^^--
806 | | |
807 | | explicit destructor calls not allowed
808 ```
809
810 This error message states that we’re not allowed to explicitly call `drop`. The
811 error message uses the term *destructor*, which is the general programming term
812 for a function that cleans up an instance. A *destructor* is analogous to a
813 *constructor*, which creates an instance. The `drop` function in Rust is one
814 particular destructor.
815
816 Rust doesn’t let us call `drop` explicitly because Rust would still
817 automatically call `drop` on the value at the end of `main`. This would cause a
818 *double free* error because Rust would be trying to clean up the same value
819 twice.
820
821 We can’t disable the automatic insertion of `drop` when a value goes out of
822 scope, and we can’t call the `drop` method explicitly. So, if we need to force
823 a value to be cleaned up early, we use the `std::mem::drop` function.
824
825 The `std::mem::drop` function is different from the `drop` method in the `Drop`
826 trait. We call it by passing as an argument the value we want to force drop.
827 The function is in the prelude, so we can modify `main` in Listing 15-15 to
828 call the `drop` function, as shown in Listing 15-16:
829
830 Filename: src/main.rs
831
832 ```
833 fn main() {
834 let c = CustomSmartPointer {
835 data: String::from("some data"),
836 };
837 println!("CustomSmartPointer created.");
838 drop(c);
839 println!("CustomSmartPointer dropped before the end of main.");
840 }
841 ```
842
843 Listing 15-16: Calling `std::mem::drop` to explicitly drop a value before it
844 goes out of scope
845
846 Running this code will print the following:
847
848 ```
849 CustomSmartPointer created.
850 Dropping CustomSmartPointer with data `some data`!
851 CustomSmartPointer dropped before the end of main.
852 ```
853
854 The text ```Dropping CustomSmartPointer with data `some data`!``` is printed
855 between the `CustomSmartPointer created.` and `CustomSmartPointer dropped
856 before the end of main.` text, showing that the `drop` method code is called to
857 drop `c` at that point.
858
859 You can use code specified in a `Drop` trait implementation in many ways to
860 make cleanup convenient and safe: for instance, you could use it to create your
861 own memory allocator! With the `Drop` trait and Rust’s ownership system, you
862 don’t have to remember to clean up because Rust does it automatically.
863
864 You also don’t have to worry about problems resulting from accidentally
865 cleaning up values still in use: the ownership system that makes sure
866 references are always valid also ensures that `drop` gets called only once when
867 the value is no longer being used.
868
869 Now that we’ve examined `Box<T>` and some of the characteristics of smart
870 pointers, let’s look at a few other smart pointers defined in the standard
871 library.
872
873 ## `Rc<T>`, the Reference Counted Smart Pointer
874
875 In the majority of cases, ownership is clear: you know exactly which variable
876 owns a given value. However, there are cases when a single value might have
877 multiple owners. For example, in graph data structures, multiple edges might
878 point to the same node, and that node is conceptually owned by all of the edges
879 that point to it. A node shouldn’t be cleaned up unless it doesn’t have any
880 edges pointing to it and so has no owners.
881
882 You have to enable multiple ownership explicitly by using the Rust type
883 `Rc<T>`, which is an abbreviation for *reference counting*. The `Rc<T>` type
884 keeps track of the number of references to a value to determine whether or not
885 the value is still in use. If there are zero references to a value, the value
886 can be cleaned up without any references becoming invalid.
887
888 Imagine `Rc<T>` as a TV in a family room. When one person enters to watch TV,
889 they turn it on. Others can come into the room and watch the TV. When the last
890 person leaves the room, they turn off the TV because it’s no longer being used.
891 If someone turns off the TV while others are still watching it, there would be
892 uproar from the remaining TV watchers!
893
894 We use the `Rc<T>` type when we want to allocate some data on the heap for
895 multiple parts of our program to read and we can’t determine at compile time
896 which part will finish using the data last. If we knew which part would finish
897 last, we could just make that part the data’s owner, and the normal ownership
898 rules enforced at compile time would take effect.
899
900 Note that `Rc<T>` is only for use in single-threaded scenarios. When we discuss
901 concurrency in Chapter 16, we’ll cover how to do reference counting in
902 multithreaded programs.
903
904 ### Using `Rc<T>` to Share Data
905
906 Let’s return to our cons list example in Listing 15-5. Recall that we defined
907 it using `Box<T>`. This time, we’ll create two lists that both share ownership
908 of a third list. Conceptually, this looks similar to Figure 15-3:
909
910 <img alt="Two lists that share ownership of a third list" src="img/trpl15-03.svg" class="center" />
911
912 Figure 15-3: Two lists, `b` and `c`, sharing ownership of a third list, `a`
913
914 We’ll create list `a` that contains 5 and then 10. Then we’ll make two more
915 lists: `b` that starts with 3 and `c` that starts with 4. Both `b` and `c`
916 lists will then continue on to the first `a` list containing 5 and 10. In other
917 words, both lists will share the first list containing 5 and 10.
918
919 Trying to implement this scenario using our definition of `List` with `Box<T>`
920 won’t work, as shown in Listing 15-17:
921
922 Filename: src/main.rs
923
924 ```
925 enum List {
926 Cons(i32, Box<List>),
927 Nil,
928 }
929
930 use crate::List::{Cons, Nil};
931
932 fn main() {
933 let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));
934 [1] let b = Cons(3, Box::new(a));
935 [2] let c = Cons(4, Box::new(a));
936 }
937 ```
938
939 Listing 15-17: Demonstrating we’re not allowed to have two lists using `Box<T>`
940 that try to share ownership of a third list
941
942 When we compile this code, we get this error:
943
944 ```
945 error[E0382]: use of moved value: `a`
946 --> src/main.rs:11:30
947 |
948 9 | let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));
949 | - move occurs because `a` has type `List`, which does not implement the `Copy` trait
950 10 | let b = Cons(3, Box::new(a));
951 | - value moved here
952 11 | let c = Cons(4, Box::new(a));
953 | ^ value used here after move
954 ```
955
956 The `Cons` variants own the data they hold, so when we create the `b` list [1],
957 `a` is moved into `b` and `b` owns `a`. Then, when we try to use `a` again when
958 creating `c` [2], we’re not allowed to because `a` has been moved.
959
960 We could change the definition of `Cons` to hold references instead, but then
961 we would have to specify lifetime parameters. By specifying lifetime
962 parameters, we would be specifying that every element in the list will live at
963 least as long as the entire list. This is the case for the elements and lists
964 in Listing 15-17, but not in every scenario.
965
966 Instead, we’ll change our definition of `List` to use `Rc<T>` in place of
967 `Box<T>`, as shown in Listing 15-18. Each `Cons` variant will now hold a value
968 and an `Rc<T>` pointing to a `List`. When we create `b`, instead of taking
969 ownership of `a`, we’ll clone the `Rc<List>` that `a` is holding, thereby
970 increasing the number of references from one to two and letting `a` and `b`
971 share ownership of the data in that `Rc<List>`. We’ll also clone `a` when
972 creating `c`, increasing the number of references from two to three. Every time
973 we call `Rc::clone`, the reference count to the data within the `Rc<List>` will
974 increase, and the data won’t be cleaned up unless there are zero references to
975 it.
976
977 Filename: src/main.rs
978
979 ```
980 enum List {
981 Cons(i32, Rc<List>),
982 Nil,
983 }
984
985 use crate::List::{Cons, Nil};
986 [1] use std::rc::Rc;
987
988 fn main() {
989 [2] let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
990 [3] let b = Cons(3, Rc::clone(&a));
991 [4] let c = Cons(4, Rc::clone(&a));
992 }
993 ```
994
995 Listing 15-18: A definition of `List` that uses `Rc<T>`
996
997 We need to add a `use` statement to bring `Rc<T>` into scope [1] because it’s
998 not in the prelude. In `main`, we create the list holding 5 and 10 and store it
999 in a new `Rc<List>` in `a` [2]. Then when we create `b` [3] and `c` [4], we
1000 call the `Rc::clone` function and pass a reference to the `Rc<List>` in `a` as
1001 an argument.
1002
1003 We could have called `a.clone()` rather than `Rc::clone(&a)`, but Rust’s
1004 convention is to use `Rc::clone` in this case. The implementation of
1005 `Rc::clone` doesn’t make a deep copy of all the data like most types’
1006 implementations of `clone` do. The call to `Rc::clone` only increments the
1007 reference count, which doesn’t take much time. Deep copies of data can take a
1008 lot of time. By using `Rc::clone` for reference counting, we can visually
1009 distinguish between the deep-copy kinds of clones and the kinds of clones that
1010 increase the reference count. When looking for performance problems in the
1011 code, we only need to consider the deep-copy clones and can disregard calls to
1012 `Rc::clone`.
1013
1014 ### Cloning an `Rc<T>` Increases the Reference Count
1015
1016 Let’s change our working example in Listing 15-18 so we can see the reference
1017 counts changing as we create and drop references to the `Rc<List>` in `a`.
1018
1019 In Listing 15-19, we’ll change `main` so it has an inner scope around list `c`;
1020 then we can see how the reference count changes when `c` goes out of scope.
1021
1022 Filename: src/main.rs
1023
1024 ```
1025 fn main() {
1026 let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
1027 println!("count after creating a = {}", Rc::strong_count(&a));
1028 let b = Cons(3, Rc::clone(&a));
1029 println!("count after creating b = {}", Rc::strong_count(&a));
1030 {
1031 let c = Cons(4, Rc::clone(&a));
1032 println!("count after creating c = {}", Rc::strong_count(&a));
1033 }
1034 println!("count after c goes out of scope = {}", Rc::strong_count(&a));
1035 }
1036 ```
1037
1038 Listing 15-19: Printing the reference count
1039
1040 At each point in the program where the reference count changes, we print the
1041 reference count, which we get by calling the `Rc::strong_count` function. This
1042 function is named `strong_count` rather than `count` because the `Rc<T>` type
1043 also has a `weak_count`; we’ll see what `weak_count` is used for in the
1044 “Preventing Reference Cycles: Turning an `Rc<T>` into a `Weak<T>`” section.
1045
1046 This code prints the following:
1047
1048 ```
1049 count after creating a = 1
1050 count after creating b = 2
1051 count after creating c = 3
1052 count after c goes out of scope = 2
1053 ```
1054
1055 We can see that the `Rc<List>` in `a` has an initial reference count of 1; then
1056 each time we call `clone`, the count goes up by 1. When `c` goes out of scope,
1057 the count goes down by 1. We don’t have to call a function to decrease the
1058 reference count like we have to call `Rc::clone` to increase the reference
1059 count: the implementation of the `Drop` trait decreases the reference count
1060 automatically when an `Rc<T>` value goes out of scope.
1061
1062 What we can’t see in this example is that when `b` and then `a` go out of scope
1063 at the end of `main`, the count is then 0, and the `Rc<List>` is cleaned up
1064 completely. Using `Rc<T>` allows a single value to have multiple owners, and
1065 the count ensures that the value remains valid as long as any of the owners
1066 still exist.
1067
1068 Via immutable references, `Rc<T>` allows you to share data between multiple
1069 parts of your program for reading only. If `Rc<T>` allowed you to have multiple
1070 mutable references too, you might violate one of the borrowing rules discussed
1071 in Chapter 4: multiple mutable borrows to the same place can cause data races
1072 and inconsistencies. But being able to mutate data is very useful! In the next
1073 section, we’ll discuss the interior mutability pattern and the `RefCell<T>`
1074 type that you can use in conjunction with an `Rc<T>` to work with this
1075 immutability restriction.
1076
1077 ## `RefCell<T>` and the Interior Mutability Pattern
1078
1079 *Interior mutability* is a design pattern in Rust that allows you to mutate
1080 data even when there are immutable references to that data; normally, this
1081 action is disallowed by the borrowing rules. To mutate data, the pattern uses
1082 `unsafe` code inside a data structure to bend Rust’s usual rules that govern
1083 mutation and borrowing. Unsafe code indicates to the compiler that we’re
1084 checking the rules manually instead of relying on the compiler to check them
1085 for us; we will discuss unsafe code more in Chapter 19.
1086
1087 We can use types that use the interior mutability pattern only when we can
1088 ensure that the borrowing rules will be followed at runtime, even though the
1089 compiler can’t guarantee that. The `unsafe` code involved is then wrapped in a
1090 safe API, and the outer type is still immutable.
1091
1092 Let’s explore this concept by looking at the `RefCell<T>` type that follows the
1093 interior mutability pattern.
1094
1095 ### Enforcing Borrowing Rules at Runtime with `RefCell<T>`
1096
1097 Unlike `Rc<T>`, the `RefCell<T>` type represents single ownership over the data
1098 it holds. So, what makes `RefCell<T>` different from a type like `Box<T>`?
1099 Recall the borrowing rules you learned in Chapter 4:
1100
1101 * At any given time, you can have *either* (but not both) one mutable reference
1102 or any number of immutable references.
1103 * References must always be valid.
1104
1105 With references and `Box<T>`, the borrowing rules’ invariants are enforced at
1106 compile time. With `RefCell<T>`, these invariants are enforced *at runtime*.
1107 With references, if you break these rules, you’ll get a compiler error. With
1108 `RefCell<T>`, if you break these rules, your program will panic and exit.
1109
1110 The advantages of checking the borrowing rules at compile time are that errors
1111 will be caught sooner in the development process, and there is no impact on
1112 runtime performance because all the analysis is completed beforehand. For those
1113 reasons, checking the borrowing rules at compile time is the best choice in the
1114 majority of cases, which is why this is Rust’s default.
1115
1116 The advantage of checking the borrowing rules at runtime instead is that
1117 certain memory-safe scenarios are then allowed, where they would’ve been
1118 disallowed by the compile-time checks. Static analysis, like the Rust compiler,
1119 is inherently conservative. Some properties of code are impossible to detect by
1120 analyzing the code: the most famous example is the Halting Problem, which is
1121 beyond the scope of this book but is an interesting topic to research.
1122
1123 Because some analysis is impossible, if the Rust compiler can’t be sure the
1124 code complies with the ownership rules, it might reject a correct program; in
1125 this way, it’s conservative. If Rust accepted an incorrect program, users
1126 wouldn’t be able to trust in the guarantees Rust makes. However, if Rust
1127 rejects a correct program, the programmer will be inconvenienced, but nothing
1128 catastrophic can occur. The `RefCell<T>` type is useful when you’re sure your
1129 code follows the borrowing rules but the compiler is unable to understand and
1130 guarantee that.
1131
1132 Similar to `Rc<T>`, `RefCell<T>` is only for use in single-threaded scenarios
1133 and will give you a compile-time error if you try using it in a multithreaded
1134 context. We’ll talk about how to get the functionality of `RefCell<T>` in a
1135 multithreaded program in Chapter 16.
1136
1137 Here is a recap of the reasons to choose `Box<T>`, `Rc<T>`, or `RefCell<T>`:
1138
1139 * `Rc<T>` enables multiple owners of the same data; `Box<T>` and `RefCell<T>`
1140 have single owners.
1141 * `Box<T>` allows immutable or mutable borrows checked at compile time; `Rc<T>`
1142 allows only immutable borrows checked at compile time; `RefCell<T>` allows
1143 immutable or mutable borrows checked at runtime.
1144 * Because `RefCell<T>` allows mutable borrows checked at runtime, you can
1145 mutate the value inside the `RefCell<T>` even when the `RefCell<T>` is
1146 immutable.
1147
1148 Mutating the value inside an immutable value is the *interior mutability*
1149 pattern. Let’s look at a situation in which interior mutability is useful and
1150 examine how it’s possible.
1151
1152 ### Interior Mutability: A Mutable Borrow to an Immutable Value
1153
1154 A consequence of the borrowing rules is that when you have an immutable value,
1155 you can’t borrow it mutably. For example, this code won’t compile:
1156
1157 ```
1158 fn main() {
1159 let x = 5;
1160 let y = &mut x;
1161 }
1162 ```
1163
1164 If you tried to compile this code, you’d get the following error:
1165
1166 ```
1167 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
1168 --> src/main.rs:3:13
1169 |
1170 2 | let x = 5;
1171 | - help: consider changing this to be mutable: `mut x`
1172 3 | let y = &mut x;
1173 | ^^^^^^ cannot borrow as mutable
1174 ```
1175
1176 However, there are situations in which it would be useful for a value to mutate
1177 itself in its methods but appear immutable to other code. Code outside the
1178 value’s methods would not be able to mutate the value. Using `RefCell<T>` is
1179 one way to get the ability to have interior mutability, but `RefCell<T>`
1180 doesn’t get around the borrowing rules completely: the borrow checker in the
1181 compiler allows this interior mutability, and the borrowing rules are checked
1182 at runtime instead. If you violate the rules, you’ll get a `panic!` instead of
1183 a compiler error.
1184
1185 Let’s work through a practical example where we can use `RefCell<T>` to mutate
1186 an immutable value and see why that is useful.
1187
1188 #### A Use Case for Interior Mutability: Mock Objects
1189
1190 Sometimes during testing a programmer will use a type in place of another type,
1191 in order to observe particular behavior and assert it's implemented correctly.
1192 This placeholder type is called a *test double*. Think of it in the sense of a
1193 "stunt double" in filmmaking, where a person steps in and substitutes for an
1194 actor to do a particular tricky scene. Test doubles stand in for other types
1195 when we're running tests. *Mock objects* are specific types of test doubles
1196 that record what happens during a test so you can assert that the correct
1197 actions took place.
1198
1199 Rust doesn’t have objects in the same sense as other languages have objects,
1200 and Rust doesn’t have mock object functionality built into the standard library
1201 as some other languages do. However, you can definitely create a struct that
1202 will serve the same purposes as a mock object.
1203
1204 Here’s the scenario we’ll test: we’ll create a library that tracks a value
1205 against a maximum value and sends messages based on how close to the maximum
1206 value the current value is. This library could be used to keep track of a
1207 user’s quota for the number of API calls they’re allowed to make, for example.
1208
1209 Our library will only provide the functionality of tracking how close to the
1210 maximum a value is and what the messages should be at what times. Applications
1211 that use our library will be expected to provide the mechanism for sending the
1212 messages: the application could put a message in the application, send an
1213 email, send a text message, or something else. The library doesn’t need to know
1214 that detail. All it needs is something that implements a trait we’ll provide
1215 called `Messenger`. Listing 15-20 shows the library code:
1216
1217 Filename: src/lib.rs
1218
1219 ```
1220 pub trait Messenger {
1221 [1] fn send(&self, msg: &str);
1222 }
1223
1224 pub struct LimitTracker<'a, T: Messenger> {
1225 messenger: &'a T,
1226 value: usize,
1227 max: usize,
1228 }
1229
1230 impl<'a, T> LimitTracker<'a, T>
1231 where
1232 T: Messenger,
1233 {
1234 pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> {
1235 LimitTracker {
1236 messenger,
1237 value: 0,
1238 max,
1239 }
1240 }
1241
1242 [2] pub fn set_value(&mut self, value: usize) {
1243 self.value = value;
1244
1245 let percentage_of_max = self.value as f64 / self.max as f64;
1246
1247 if percentage_of_max >= 1.0 {
1248 self.messenger.send("Error: You are over your quota!");
1249 } else if percentage_of_max >= 0.9 {
1250 self.messenger
1251 .send("Urgent warning: You've used up over 90% of your quota!");
1252 } else if percentage_of_max >= 0.75 {
1253 self.messenger
1254 .send("Warning: You've used up over 75% of your quota!");
1255 }
1256 }
1257 }
1258 ```
1259
1260 Listing 15-20: A library to keep track of how close a value is to a maximum
1261 value and warn when the value is at certain levels
1262
1263 One important part of this code is that the `Messenger` trait has one method
1264 called `send` that takes an immutable reference to `self` and the text of the
1265 message [1]. This trait is the interface our mock object needs to implement so
1266 that the mock can be used in the same way a real object is. The other important
1267 part is that we want to test the behavior of the `set_value` method on the
1268 `LimitTracker` [2]. We can change what we pass in for the `value` parameter,
1269 but `set_value` doesn’t return anything for us to make assertions on. We want
1270 to be able to say that if we create a `LimitTracker` with something that
1271 implements the `Messenger` trait and a particular value for `max`, when we pass
1272 different numbers for `value`, the messenger is told to send the appropriate
1273 messages.
1274
1275 We need a mock object that, instead of sending an email or text message when we
1276 call `send`, will only keep track of the messages it’s told to send. We can
1277 create a new instance of the mock object, create a `LimitTracker` that uses the
1278 mock object, call the `set_value` method on `LimitTracker`, and then check that
1279 the mock object has the messages we expect. Listing 15-21 shows an attempt to
1280 implement a mock object to do just that, but the borrow checker won’t allow it:
1281
1282 Filename: src/lib.rs
1283
1284 ```
1285 #[cfg(test)]
1286 mod tests {
1287 use super::*;
1288
1289 [1] struct MockMessenger {
1290 [2] sent_messages: Vec<String>,
1291 }
1292
1293 impl MockMessenger {
1294 [3] fn new() -> MockMessenger {
1295 MockMessenger {
1296 sent_messages: vec![],
1297 }
1298 }
1299 }
1300
1301 [4] impl Messenger for MockMessenger {
1302 fn send(&self, message: &str) {
1303 [5] self.sent_messages.push(String::from(message));
1304 }
1305 }
1306
1307 #[test]
1308 [6] fn it_sends_an_over_75_percent_warning_message() {
1309 let mock_messenger = MockMessenger::new();
1310 let mut limit_tracker = LimitTracker::new(&mock_messenger, 100);
1311
1312 limit_tracker.set_value(80);
1313
1314 assert_eq!(mock_messenger.sent_messages.len(), 1);
1315 }
1316 }
1317 ```
1318
1319 Listing 15-21: An attempt to implement a `MockMessenger` that isn’t allowed by
1320 the borrow checker
1321
1322 This test code defines a `MockMessenger` struct [1] that has a `sent_messages`
1323 field with a `Vec` of `String` values [2] to keep track of the messages it’s
1324 told to send. We also define an associated function `new` [3] to make it
1325 convenient to create new `MockMessenger` values that start with an empty list
1326 of messages. We then implement the `Messenger` trait for `MockMessenger` [4] so
1327 we can give a `MockMessenger` to a `LimitTracker`. In the definition of the
1328 `send` method [5], we take the message passed in as a parameter and store it in
1329 the `MockMessenger` list of `sent_messages`.
1330
1331 In the test, we’re testing what happens when the `LimitTracker` is told to set
1332 `value` to something that is more than 75 percent of the `max` value [6].
1333 First, we create a new `MockMessenger`, which will start with an empty list of
1334 messages. Then we create a new `LimitTracker` and give it a reference to the
1335 new `MockMessenger` and a `max` value of 100. We call the `set_value` method on
1336 the `LimitTracker` with a value of 80, which is more than 75 percent of 100.
1337 Then we assert that the list of messages that the `MockMessenger` is keeping
1338 track of should now have one message in it.
1339
1340 However, there’s one problem with this test, as shown here:
1341
1342 ```
1343 error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind a `&` reference
1344 --> src/lib.rs:58:13
1345 |
1346 2 | fn send(&self, msg: &str);
1347 | ----- help: consider changing that to be a mutable reference: `&mut self`
1348 ...
1349 58 | self.sent_messages.push(String::from(message));
1350 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
1351 ```
1352
1353 We can’t modify the `MockMessenger` to keep track of the messages, because the
1354 `send` method takes an immutable reference to `self`. We also can’t take the
1355 suggestion from the error text to use `&mut self` instead, because then the
1356 signature of `send` wouldn’t match the signature in the `Messenger` trait
1357 definition (feel free to try and see what error message you get).
1358
1359 This is a situation in which interior mutability can help! We’ll store the
1360 `sent_messages` within a `RefCell<T>`, and then the `send` method will be
1361 able to modify `sent_messages` to store the messages we’ve seen. Listing 15-22
1362 shows what that looks like:
1363
1364 Filename: src/lib.rs
1365
1366 ```
1367 #[cfg(test)]
1368 mod tests {
1369 use super::*;
1370 use std::cell::RefCell;
1371
1372 struct MockMessenger {
1373 [1] sent_messages: RefCell<Vec<String>>,
1374 }
1375
1376 impl MockMessenger {
1377 fn new() -> MockMessenger {
1378 MockMessenger {
1379 sent_messages: RefCell::new(vec![]) [2],
1380 }
1381 }
1382 }
1383
1384 impl Messenger for MockMessenger {
1385 fn send(&self, message: &str) {
1386 [3] self.sent_messages.borrow_mut().push(String::from(message));
1387 }
1388 }
1389
1390 #[test]
1391 fn it_sends_an_over_75_percent_warning_message() {
1392 // --snip--
1393
1394 [4] assert_eq!(mock_messenger.sent_messages.borrow().len(), 1);
1395 }
1396 }
1397 ```
1398
1399 Listing 15-22: Using `RefCell<T>` to mutate an inner value while the outer
1400 value is considered immutable
1401
1402 The `sent_messages` field is now of type `RefCell<Vec<String>>` [1] instead of
1403 `Vec<String>`. In the `new` function, we create a new `RefCell<Vec<String>>`
1404 instance around the empty vector [2].
1405
1406 For the implementation of the `send` method, the first parameter is still an
1407 immutable borrow of `self`, which matches the trait definition. We call
1408 `borrow_mut` on the `RefCell<Vec<String>>` in `self.sent_messages` [3] to get a
1409 mutable reference to the value inside the `RefCell<Vec<String>>`, which is
1410 the vector. Then we can call `push` on the mutable reference to the vector to
1411 keep track of the messages sent during the test.
1412
1413 The last change we have to make is in the assertion: to see how many items are
1414 in the inner vector, we call `borrow` on the `RefCell<Vec<String>>` to get an
1415 immutable reference to the vector [4].
1416
1417 Now that you’ve seen how to use `RefCell<T>`, let’s dig into how it works!
1418
1419 #### Keeping Track of Borrows at Runtime with `RefCell<T>`
1420
1421 When creating immutable and mutable references, we use the `&` and `&mut`
1422 syntax, respectively. With `RefCell<T>`, we use the `borrow` and `borrow_mut`
1423 methods, which are part of the safe API that belongs to `RefCell<T>`. The
1424 `borrow` method returns the smart pointer type `Ref<T>`, and `borrow_mut`
1425 returns the smart pointer type `RefMut<T>`. Both types implement `Deref`, so we
1426 can treat them like regular references.
1427
1428 The `RefCell<T>` keeps track of how many `Ref<T>` and `RefMut<T>` smart
1429 pointers are currently active. Every time we call `borrow`, the `RefCell<T>`
1430 increases its count of how many immutable borrows are active. When a `Ref<T>`
1431 value goes out of scope, the count of immutable borrows goes down by one. Just
1432 like the compile-time borrowing rules, `RefCell<T>` lets us have many immutable
1433 borrows or one mutable borrow at any point in time.
1434
1435 If we try to violate these rules, rather than getting a compiler error as we
1436 would with references, the implementation of `RefCell<T>` will panic at
1437 runtime. Listing 15-23 shows a modification of the implementation of `send` in
1438 Listing 15-22. We’re deliberately trying to create two mutable borrows active
1439 for the same scope to illustrate that `RefCell<T>` prevents us from doing this
1440 at runtime.
1441
1442 Filename: src/lib.rs
1443
1444 ```
1445 impl Messenger for MockMessenger {
1446 fn send(&self, message: &str) {
1447 let mut one_borrow = self.sent_messages.borrow_mut();
1448 let mut two_borrow = self.sent_messages.borrow_mut();
1449
1450 one_borrow.push(String::from(message));
1451 two_borrow.push(String::from(message));
1452 }
1453 }
1454 ```
1455
1456 Listing 15-23: Creating two mutable references in the same scope to see that
1457 `RefCell<T>` will panic
1458
1459 We create a variable `one_borrow` for the `RefMut<T>` smart pointer returned
1460 from `borrow_mut`. Then we create another mutable borrow in the same way in the
1461 variable `two_borrow`. This makes two mutable references in the same scope,
1462 which isn’t allowed. When we run the tests for our library, the code in Listing
1463 15-23 will compile without any errors, but the test will fail:
1464
1465 ```
1466 ---- tests::it_sends_an_over_75_percent_warning_message stdout ----
1467 thread 'main' panicked at 'already borrowed: BorrowMutError', src/lib.rs:60:53
1468 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1469 ```
1470
1471 Notice that the code panicked with the message `already borrowed:
1472 BorrowMutError`. This is how `RefCell<T>` handles violations of the borrowing
1473 rules at runtime.
1474
1475 Choosing to catch borrowing errors at runtime rather than compile time, as
1476 we've done here, means you'd potentially be finding mistakes in your code later
1477 in the development process: possibly not until your code was deployed to
1478 production. Also, your code would incur a small runtime performance penalty as
1479 a result of keeping track of the borrows at runtime rather than compile time.
1480 However, using `RefCell<T>` makes it possible to write a mock object that can
1481 modify itself to keep track of the messages it has seen while you’re using it
1482 in a context where only immutable values are allowed. You can use `RefCell<T>`
1483 despite its trade-offs to get more functionality than regular references
1484 provide.
1485
1486 ### Having Multiple Owners of Mutable Data by Combining `Rc<T>` and `RefCell<T>`
1487
1488 A common way to use `RefCell<T>` is in combination with `Rc<T>`. Recall that
1489 `Rc<T>` lets you have multiple owners of some data, but it only gives immutable
1490 access to that data. If you have an `Rc<T>` that holds a `RefCell<T>`, you can
1491 get a value that can have multiple owners *and* that you can mutate!
1492
1493 For example, recall the cons list example in Listing 15-18 where we used
1494 `Rc<T>` to allow multiple lists to share ownership of another list. Because
1495 `Rc<T>` holds only immutable values, we can’t change any of the values in the
1496 list once we’ve created them. Let’s add in `RefCell<T>` to gain the ability to
1497 change the values in the lists. Listing 15-24 shows that by using a
1498 `RefCell<T>` in the `Cons` definition, we can modify the value stored in all
1499 the lists:
1500
1501 Filename: src/main.rs
1502
1503 ```
1504 #[derive(Debug)]
1505 enum List {
1506 Cons(Rc<RefCell<i32>>, Rc<List>),
1507 Nil,
1508 }
1509
1510 use crate::List::{Cons, Nil};
1511 use std::cell::RefCell;
1512 use std::rc::Rc;
1513
1514 fn main() {
1515 [1] let value = Rc::new(RefCell::new(5));
1516
1517 [2] let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));
1518
1519 let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
1520 let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
1521
1522 [3] *value.borrow_mut() += 10;
1523
1524 println!("a after = {:?}", a);
1525 println!("b after = {:?}", b);
1526 println!("c after = {:?}", c);
1527 }
1528 ```
1529
1530 Listing 15-24: Using `Rc<RefCell<i32>>` to create a `List` that we can mutate
1531
1532 We create a value that is an instance of `Rc<RefCell<i32>>` and store it in a
1533 variable named `value` [1] so we can access it directly later. Then we create a
1534 `List` in `a` with a `Cons` variant that holds `value` [2]. We need to clone
1535 `value` so both `a` and `value` have ownership of the inner `5` value rather
1536 than transferring ownership from `value` to `a` or having `a` borrow from
1537 `value`.
1538
1539 We wrap the list `a` in an `Rc<T>` so when we create lists `b` and `c`, they
1540 can both refer to `a`, which is what we did in Listing 15-18.
1541
1542 After we’ve created the lists in `a`, `b`, and `c`, we want to add 10 to the
1543 value in `value` [3]. We do this by calling `borrow_mut` on `value`, which uses
1544 the automatic dereferencing feature we discussed in Chapter 5 (see the section
1545 “Where’s the `->` Operator?”) to dereference the `Rc<T>` to the inner
1546 `RefCell<T>` value. The `borrow_mut` method returns a `RefMut<T>` smart
1547 pointer, and we use the dereference operator on it and change the inner value.
1548
1549 When we print `a`, `b`, and `c`, we can see that they all have the modified
1550 value of 15 rather than 5:
1551
1552 ```
1553 a after = Cons(RefCell { value: 15 }, Nil)
1554 b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil))
1555 c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil))
1556 ```
1557
1558 This technique is pretty neat! By using `RefCell<T>`, we have an outwardly
1559 immutable `List` value. But we can use the methods on `RefCell<T>` that provide
1560 access to its interior mutability so we can modify our data when we need to.
1561 The runtime checks of the borrowing rules protect us from data races, and it’s
1562 sometimes worth trading a bit of speed for this flexibility in our data
1563 structures. Note that `RefCell<T>` does not work for multithreaded code!
1564 `Mutex<T>` is the thread-safe version of `RefCell<T>` and we’ll discuss
1565 `Mutex<T>` in Chapter 16.
1566
1567 ## Reference Cycles Can Leak Memory
1568
1569 Rust’s memory safety guarantees make it difficult, but not impossible, to
1570 accidentally create memory that is never cleaned up (known as a *memory leak*).
1571 Preventing memory leaks entirely is not one of Rust’s guarantees, meaning
1572 memory leaks are memory safe in Rust. We can see that Rust allows memory leaks
1573 by using `Rc<T>` and `RefCell<T>`: it’s possible to create references where
1574 items refer to each other in a cycle. This creates memory leaks because the
1575 reference count of each item in the cycle will never reach 0, and the values
1576 will never be dropped.
1577
1578 ### Creating a Reference Cycle
1579
1580 Let’s look at how a reference cycle might happen and how to prevent it,
1581 starting with the definition of the `List` enum and a `tail` method in Listing
1582 15-25:
1583
1584 Filename: src/main.rs
1585
1586 ```
1587 use crate::List::{Cons, Nil};
1588 use std::cell::RefCell;
1589 use std::rc::Rc;
1590
1591 #[derive(Debug)]
1592 enum List {
1593 [1] Cons(i32, RefCell<Rc<List>>),
1594 Nil,
1595 }
1596
1597 impl List {
1598 [2] fn tail(&self) -> Option<&RefCell<Rc<List>>> {
1599 match self {
1600 Cons(_, item) => Some(item),
1601 Nil => None,
1602 }
1603 }
1604 }
1605 ```
1606
1607 Listing 15-25: A cons list definition that holds a `RefCell<T>` so we can
1608 modify what a `Cons` variant is referring to
1609
1610 We’re using another variation of the `List` definition from Listing 15-5. The
1611 second element in the `Cons` variant is now `RefCell<Rc<List>>` [1], meaning
1612 that instead of having the ability to modify the `i32` value as we did in
1613 Listing 15-24, we want to modify the `List` value a `Cons` variant is
1614 pointing to. We’re also adding a `tail` method [2] to make it convenient for us
1615 to access the second item if we have a `Cons` variant.
1616
1617 In Listing 15-26, we’re adding a `main` function that uses the definitions in
1618 Listing 15-25. This code creates a list in `a` and a list in `b` that points to
1619 the list in `a`. Then it modifies the list in `a` to point to `b`, creating a
1620 reference cycle. There are `println!` statements along the way to show what the
1621 reference counts are at various points in this process.
1622
1623 Filename: src/main.rs
1624
1625 ```
1626 fn main() {
1627 [1] let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));
1628
1629 println!("a initial rc count = {}", Rc::strong_count(&a));
1630 println!("a next item = {:?}", a.tail());
1631
1632 [2] let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));
1633
1634 println!("a rc count after b creation = {}", Rc::strong_count(&a));
1635 println!("b initial rc count = {}", Rc::strong_count(&b));
1636 println!("b next item = {:?}", b.tail());
1637
1638 [3] if let Some(link) = a.tail() {
1639 [4] *link.borrow_mut() = Rc::clone(&b);
1640 }
1641
1642 println!("b rc count after changing a = {}", Rc::strong_count(&b));
1643 println!("a rc count after changing a = {}", Rc::strong_count(&a));
1644
1645 // Uncomment the next line to see that we have a cycle;
1646 // it will overflow the stack
1647 // println!("a next item = {:?}", a.tail());
1648 }
1649 ```
1650
1651 Listing 15-26: Creating a reference cycle of two `List` values pointing to each
1652 other
1653
1654 We create an `Rc<List>` instance holding a `List` value in the variable `a`
1655 with an initial list of `5, Nil` [1]. We then create an `Rc<List>` instance
1656 holding another `List` value in the variable `b` that contains the value 10 and
1657 points to the list in `a` [2].
1658
1659 We modify `a` so it points to `b` instead of `Nil`, creating a cycle. We do
1660 that by using the `tail` method to get a reference to the `RefCell<Rc<List>>`
1661 in `a`, which we put in the variable `link` [3]. Then we use the `borrow_mut`
1662 method on the `RefCell<Rc<List>>` to change the value inside from an `Rc<List>`
1663 that holds a `Nil` value to the `Rc<List>` in `b` [4].
1664
1665 When we run this code, keeping the last `println!` commented out for the
1666 moment, we’ll get this output:
1667
1668 ```
1669 a initial rc count = 1
1670 a next item = Some(RefCell { value: Nil })
1671 a rc count after b creation = 2
1672 b initial rc count = 1
1673 b next item = Some(RefCell { value: Cons(5, RefCell { value: Nil }) })
1674 b rc count after changing a = 2
1675 a rc count after changing a = 2
1676 ```
1677
1678 The reference count of the `Rc<List>` instances in both `a` and `b` are 2 after
1679 we change the list in `a` to point to `b`. At the end of `main`, Rust drops the
1680 variable `b`, which decreases the reference count of the `b` `Rc<List>` instance
1681 from 2 to 1. The memory that `Rc<List>` has on the heap won’t be dropped at
1682 this point, because its reference count is 1, not 0. Then Rust drops `a`, which
1683 decreases the reference count of the `a` `Rc<List>` instance from 2 to 1 as
1684 well. This instance’s memory can’t be dropped either, because the other
1685 `Rc<List>` instance still refers to it. The memory allocated to the list will
1686 remain uncollected forever. To visualize this reference cycle, we’ve created a
1687 diagram in Figure 15-4.
1688
1689 <img alt="Reference cycle of lists" src="img/trpl15-04.svg" class="center" />
1690
1691 Figure 15-4: A reference cycle of lists `a` and `b` pointing to each other
1692
1693 If you uncomment the last `println!` and run the program, Rust will try to
1694 print this cycle with `a` pointing to `b` pointing to `a` and so forth until it
1695 overflows the stack.
1696
1697 Compared to a real-world program, the consequences creating a reference cycle
1698 in this example aren’t very dire: right after we create the reference cycle,
1699 the program ends. However, if a more complex program allocated lots of memory
1700 in a cycle and held onto it for a long time, the program would use more memory
1701 than it needed and might overwhelm the system, causing it to run out of
1702 available memory.
1703
1704 Creating reference cycles is not easily done, but it’s not impossible either.
1705 If you have `RefCell<T>` values that contain `Rc<T>` values or similar nested
1706 combinations of types with interior mutability and reference counting, you must
1707 ensure that you don’t create cycles; you can’t rely on Rust to catch them.
1708 Creating a reference cycle would be a logic bug in your program that you should
1709 use automated tests, code reviews, and other software development practices to
1710 minimize.
1711
1712 Another solution for avoiding reference cycles is reorganizing your data
1713 structures so that some references express ownership and some references don’t.
1714 As a result, you can have cycles made up of some ownership relationships and
1715 some non-ownership relationships, and only the ownership relationships affect
1716 whether or not a value can be dropped. In Listing 15-25, we always want `Cons`
1717 variants to own their list, so reorganizing the data structure isn’t possible.
1718 Let’s look at an example using graphs made up of parent nodes and child nodes
1719 to see when non-ownership relationships are an appropriate way to prevent
1720 reference cycles.
1721
1722 ### Preventing Reference Cycles: Turning an `Rc<T>` into a `Weak<T>`
1723
1724 So far, we’ve demonstrated that calling `Rc::clone` increases the
1725 `strong_count` of an `Rc<T>` instance, and an `Rc<T>` instance is only cleaned
1726 up if its `strong_count` is 0. You can also create a *weak reference* to the
1727 value within an `Rc<T>` instance by calling `Rc::downgrade` and passing a
1728 reference to the `Rc<T>`. Strong references are how you can share ownership of
1729 an `Rc<T>` instance. Weak references don’t express an ownership relationship,
1730 and their count doesn't affect when an `Rc<T>` instance is cleaned up. They
1731 won’t cause a reference cycle because any cycle involving some weak references
1732 will be broken once the strong reference count of values involved is 0.
1733
1734 When you call `Rc::downgrade`, you get a smart pointer of type `Weak<T>`.
1735 Instead of increasing the `strong_count` in the `Rc<T>` instance by 1, calling
1736 `Rc::downgrade` increases the `weak_count` by 1. The `Rc<T>` type uses
1737 `weak_count` to keep track of how many `Weak<T>` references exist, similar to
1738 `strong_count`. The difference is the `weak_count` doesn’t need to be 0 for the
1739 `Rc<T>` instance to be cleaned up.
1740
1741 Because the value that `Weak<T>` references might have been dropped, to do
1742 anything with the value that a `Weak<T>` is pointing to, you must make sure the
1743 value still exists. Do this by calling the `upgrade` method on a `Weak<T>`
1744 instance, which will return an `Option<Rc<T>>`. You’ll get a result of `Some`
1745 if the `Rc<T>` value has not been dropped yet and a result of `None` if the
1746 `Rc<T>` value has been dropped. Because `upgrade` returns an `Option<Rc<T>>`,
1747 Rust will ensure that the `Some` case and the `None` case are handled, and
1748 there won’t be an invalid pointer.
1749
1750 As an example, rather than using a list whose items know only about the next
1751 item, we’ll create a tree whose items know about their children items *and*
1752 their parent items.
1753
1754 #### Creating a Tree Data Structure: a `Node` with Child Nodes
1755
1756 To start, we’ll build a tree with nodes that know about their child nodes.
1757 We’ll create a struct named `Node` that holds its own `i32` value as well as
1758 references to its children `Node` values:
1759
1760 Filename: src/main.rs
1761
1762 ```
1763 use std::cell::RefCell;
1764 use std::rc::Rc;
1765
1766 #[derive(Debug)]
1767 struct Node {
1768 value: i32,
1769 children: RefCell<Vec<Rc<Node>>>,
1770 }
1771 ```
1772
1773 We want a `Node` to own its children, and we want to share that ownership with
1774 variables so we can access each `Node` in the tree directly. To do this, we
1775 define the `Vec<T>` items to be values of type `Rc<Node>`. We also want to
1776 modify which nodes are children of another node, so we have a `RefCell<T>` in
1777 `children` around the `Vec<Rc<Node>>`.
1778
1779 Next, we’ll use our struct definition and create one `Node` instance named
1780 `leaf` with the value 3 and no children, and another instance named `branch`
1781 with the value 5 and `leaf` as one of its children, as shown in Listing 15-27:
1782
1783 Filename: src/main.rs
1784
1785 ```
1786 fn main() {
1787 let leaf = Rc::new(Node {
1788 value: 3,
1789 children: RefCell::new(vec![]),
1790 });
1791
1792 let branch = Rc::new(Node {
1793 value: 5,
1794 children: RefCell::new(vec![Rc::clone(&leaf)]),
1795 });
1796 }
1797 ```
1798
1799 Listing 15-27: Creating a `leaf` node with no children and a `branch` node with
1800 `leaf` as one of its children
1801
1802 We clone the `Rc<Node>` in `leaf` and store that in `branch`, meaning the
1803 `Node` in `leaf` now has two owners: `leaf` and `branch`. We can get from
1804 `branch` to `leaf` through `branch.children`, but there’s no way to get from
1805 `leaf` to `branch`. The reason is that `leaf` has no reference to `branch` and
1806 doesn’t know they’re related. We want `leaf` to know that `branch` is its
1807 parent. We’ll do that next.
1808
1809 #### Adding a Reference from a Child to Its Parent
1810
1811 To make the child node aware of its parent, we need to add a `parent` field to
1812 our `Node` struct definition. The trouble is in deciding what the type of
1813 `parent` should be. We know it can’t contain an `Rc<T>`, because that would
1814 create a reference cycle with `leaf.parent` pointing to `branch` and
1815 `branch.children` pointing to `leaf`, which would cause their `strong_count`
1816 values to never be 0.
1817
1818 Thinking about the relationships another way, a parent node should own its
1819 children: if a parent node is dropped, its child nodes should be dropped as
1820 well. However, a child should not own its parent: if we drop a child node, the
1821 parent should still exist. This is a case for weak references!
1822
1823 So instead of `Rc<T>`, we’ll make the type of `parent` use `Weak<T>`,
1824 specifically a `RefCell<Weak<Node>>`. Now our `Node` struct definition looks
1825 like this:
1826
1827 Filename: src/main.rs
1828
1829 ```
1830 use std::cell::RefCell;
1831 use std::rc::{Rc, Weak};
1832
1833 #[derive(Debug)]
1834 struct Node {
1835 value: i32,
1836 parent: RefCell<Weak<Node>>,
1837 children: RefCell<Vec<Rc<Node>>>,
1838 }
1839 ```
1840
1841 A node will be able to refer to its parent node but doesn’t own its parent.
1842 In Listing 15-28, we update `main` to use this new definition so the `leaf`
1843 node will have a way to refer to its parent, `branch`:
1844
1845 Filename: src/main.rs
1846
1847 ```
1848 fn main() {
1849 let leaf = Rc::new(Node {
1850 value: 3,
1851 [1] parent: RefCell::new(Weak::new()),
1852 children: RefCell::new(vec![]),
1853 });
1854
1855 [2] println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
1856
1857 let branch = Rc::new(Node {
1858 value: 5,
1859 [3] parent: RefCell::new(Weak::new()),
1860 children: RefCell::new(vec![Rc::clone(&leaf)]),
1861 });
1862
1863 [4] *leaf.parent.borrow_mut() = Rc::downgrade(&branch);
1864
1865 [5] println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
1866 }
1867 ```
1868
1869 Listing 15-28: A `leaf` node with a weak reference to its parent node `branch`
1870
1871 Creating the `leaf` node looks similar to Listing 15-27 with the exception of
1872 the `parent` field: `leaf` starts out without a parent, so we create a new,
1873 empty `Weak<Node>` reference instance [1].
1874
1875 At this point, when we try to get a reference to the parent of `leaf` by using
1876 the `upgrade` method, we get a `None` value. We see this in the output from the
1877 first `println!` statement [2]:
1878
1879 ```
1880 leaf parent = None
1881 ```
1882
1883 When we create the `branch` node, it will also have a new `Weak<Node>`
1884 reference in the `parent` field [3], because `branch` doesn’t have a parent
1885 node. We still have `leaf` as one of the children of `branch`. Once we have the
1886 `Node` instance in `branch`, we can modify `leaf` to give it a `Weak<Node>`
1887 reference to its parent [4]. We use the `borrow_mut` method on the
1888 `RefCell<Weak<Node>>` in the `parent` field of `leaf`, and then we use the
1889 `Rc::downgrade` function to create a `Weak<Node>` reference to `branch` from
1890 the `Rc<Node>` in `branch.`
1891
1892 When we print the parent of `leaf` again [5], this time we’ll get a `Some`
1893 variant holding `branch`: now `leaf` can access its parent! When we print
1894 `leaf`, we also avoid the cycle that eventually ended in a stack overflow like
1895 we had in Listing 15-26; the `Weak<Node>` references are printed as `(Weak)`:
1896
1897 ```
1898 leaf parent = Some(Node { value: 5, parent: RefCell { value: (Weak) },
1899 children: RefCell { value: [Node { value: 3, parent: RefCell { value: (Weak) },
1900 children: RefCell { value: [] } }] } })
1901 ```
1902
1903 The lack of infinite output indicates that this code didn’t create a reference
1904 cycle. We can also tell this by looking at the values we get from calling
1905 `Rc::strong_count` and `Rc::weak_count`.
1906
1907 #### Visualizing Changes to `strong_count` and `weak_count`
1908
1909 Let’s look at how the `strong_count` and `weak_count` values of the `Rc<Node>`
1910 instances change by creating a new inner scope and moving the creation of
1911 `branch` into that scope. By doing so, we can see what happens when `branch` is
1912 created and then dropped when it goes out of scope. The modifications are shown
1913 in Listing 15-29:
1914
1915 Filename: src/main.rs
1916
1917 ```
1918 fn main() {
1919 let leaf = Rc::new(Node {
1920 value: 3,
1921 parent: RefCell::new(Weak::new()),
1922 children: RefCell::new(vec![]),
1923 });
1924
1925 [1] println!(
1926 "leaf strong = {}, weak = {}",
1927 Rc::strong_count(&leaf),
1928 Rc::weak_count(&leaf),
1929 );
1930
1931 [2] {
1932 let branch = Rc::new(Node {
1933 value: 5,
1934 parent: RefCell::new(Weak::new()),
1935 children: RefCell::new(vec![Rc::clone(&leaf)]),
1936 });
1937
1938 *leaf.parent.borrow_mut() = Rc::downgrade(&branch);
1939
1940 [3] println!(
1941 "branch strong = {}, weak = {}",
1942 Rc::strong_count(&branch),
1943 Rc::weak_count(&branch),
1944 );
1945
1946 [4] println!(
1947 "leaf strong = {}, weak = {}",
1948 Rc::strong_count(&leaf),
1949 Rc::weak_count(&leaf),
1950 );
1951 [5] }
1952
1953 [6] println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
1954 [7] println!(
1955 "leaf strong = {}, weak = {}",
1956 Rc::strong_count(&leaf),
1957 Rc::weak_count(&leaf),
1958 );
1959 }
1960 ```
1961
1962 Listing 15-29: Creating `branch` in an inner scope and examining strong and
1963 weak reference counts
1964
1965 After `leaf` is created, its `Rc<Node>` has a strong count of 1 and a weak
1966 count of 0 [1]. In the inner scope [2], we create `branch` and associate it
1967 with `leaf`, at which point when we print the counts [3], the `Rc<Node>` in
1968 `branch` will have a strong count of 1 and a weak count of 1 (for `leaf.parent`
1969 pointing to `branch` with a `Weak<Node>`). When we print the counts in `leaf`
1970 [4], we’ll see it will have a strong count of 2, because `branch` now has a
1971 clone of the `Rc<Node>` of `leaf` stored in `branch.children`, but will still
1972 have a weak count of 0.
1973
1974 When the inner scope ends [5], `branch` goes out of scope and the strong count
1975 of the `Rc<Node>` decreases to 0, so its `Node` is dropped. The weak count of 1
1976 from `leaf.parent` has no bearing on whether or not `Node` is dropped, so we
1977 don’t get any memory leaks!
1978
1979 If we try to access the parent of `leaf` after the end of the scope, we’ll get
1980 `None` again [6]. At the end of the program [7], the `Rc<Node>` in `leaf` has a
1981 strong count of 1 and a weak count of 0, because the variable `leaf` is now the
1982 only reference to the `Rc<Node>` again.
1983
1984 All of the logic that manages the counts and value dropping is built into
1985 `Rc<T>` and `Weak<T>` and their implementations of the `Drop` trait. By
1986 specifying that the relationship from a child to its parent should be a
1987 `Weak<T>` reference in the definition of `Node`, you’re able to have parent
1988 nodes point to child nodes and vice versa without creating a reference cycle
1989 and memory leaks.
1990
1991 ## Summary
1992
1993 This chapter covered how to use smart pointers to make different guarantees and
1994 trade-offs from those Rust makes by default with regular references. The
1995 `Box<T>` type has a known size and points to data allocated on the heap. The
1996 `Rc<T>` type keeps track of the number of references to data on the heap so
1997 that data can have multiple owners. The `RefCell<T>` type with its interior
1998 mutability gives us a type that we can use when we need an immutable type but
1999 need to change an inner value of that type; it also enforces the borrowing
2000 rules at runtime instead of at compile time.
2001
2002 Also discussed were the `Deref` and `Drop` traits, which enable a lot of the
2003 functionality of smart pointers. We explored reference cycles that can cause
2004 memory leaks and how to prevent them using `Weak<T>`.
2005
2006 If this chapter has piqued your interest and you want to implement your own
2007 smart pointers, check out “The Rustonomicon” at
2008 *https://doc.rust-lang.org/stable/nomicon/* for more useful information.
2009
2010 Next, we’ll talk about concurrency in Rust. You’ll even learn about a few new
2011 smart pointers.