Skip to content

Commit 017f511

Browse files
Merge pull request #898 from rust-lang/ch15-edits
[READY FOR REVIEW] Ch15 edits
2 parents 089403a + fc3a73d commit 017f511

13 files changed

+3662
-1551
lines changed

second-edition/dictionary.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ ctrl
7070
Ctrl
7171
customizable
7272
CustomSmartPointer
73+
CustomSmartPointers
74+
deallocate
7375
deallocated
7476
deallocating
7577
deallocation
@@ -193,6 +195,7 @@ librarys
193195
libreoffice
194196
libstd
195197
lifecycle
198+
LimitTracker
196199
lobally
197200
locators
198201
login
@@ -210,6 +213,7 @@ Mibbit
210213
minigrep
211214
mixup
212215
mkdir
216+
MockMessenger
213217
modifiability
214218
modularity
215219
monomorphization
@@ -224,6 +228,7 @@ Mutex
224228
mutexes
225229
Mutexes
226230
MutexGuard
231+
MyBox
227232
namespace
228233
namespaced
229234
namespaces

second-edition/nostarch/chapter15.md

Lines changed: 1834 additions & 764 deletions
Large diffs are not rendered by default.
Lines changed: 87 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,97 @@
11
# Smart Pointers
22

3-
*Pointer* is a generic programming term for something that refers to a location
4-
that stores some other data. We learned about Rust’s references in Chapter 4;
5-
they’re a plain sort of pointer indicated by the `&` symbol and borrow the
6-
value that they point to. *Smart pointers* are data structures that act like a
7-
pointer, but also have additional metadata and capabilities, such as reference
8-
counting. The smart pointer pattern originated in C++. In Rust, an additional
9-
difference between plain references and smart pointers is that references are a
10-
kind of pointer that only borrow data; by contrast, in many cases, smart
11-
pointers *own* the data that they point to.
12-
13-
We’ve actually already encountered a few smart pointers in this book, even
14-
though we didn’t call them that by name at the time. For example, in a certain
15-
sense, `String` and `Vec<T>` from Chapter 8 are both smart pointers. They own
16-
some memory and allow you to manipulate it, and have metadata (like their
17-
capacity) and extra capabilities or guarantees (`String` data will always be
18-
valid UTF-8). The characteristics that distinguish a smart pointer from an
19-
ordinary struct are that smart pointers implement the `Deref` and `Drop`
20-
traits, and in this chapter we’ll be discussing both of those traits and why
21-
they’re important to smart pointers.
3+
A *pointer* is a general concept for a variable that contains an address in
4+
memory. This address refers to, or “points at”, some other data. The most
5+
common kind of pointer in Rust is a *reference*, which we learned about in
6+
Chapter 4. References are indicated by the `&` symbol and borrow the value that
7+
they point to. They don’t have any special abilities other than referring to
8+
data. They also don’t have any overhead, so they’re used the most often.
9+
10+
*Smart pointers*, on the other hand, are data structures that act like a
11+
pointer, but they also have additional metadata and capabilities. The concept
12+
of smart pointers isn’t unique to Rust; it originated in C++ and exists in
13+
other languages as well. The different smart pointers defined in Rust’s
14+
standard library provide extra functionality beyond what references provide.
15+
One example that we’ll explore in this chapter is the *reference counting*
16+
smart pointer type, which enables you to have multiple owners of data. The
17+
reference counting smart pointer keeps track of how many owners there are, and
18+
when there aren’t any remaining, the smart pointer takes care of cleaning up
19+
the data.
20+
21+
<!-- maybe a brief explanation what deref and drop? I'm not really sure what
22+
reference counting is here too, can you outline that in brief?-->
23+
<!-- We've added a quick explanation of reference counting here and a brief
24+
explanation of deref and drop below. /Carol -->
25+
26+
<!--(regarding C++) if this is relevant here, can you expand? Are we saying
27+
they will be familiar to C++ people? -->
28+
<!-- We were trying to say that "smart pointer" isn't something particular to
29+
Rust; we've tried to clarify. /Carol -->
30+
31+
In Rust, where we have the concept of ownership and borrowing, an additional
32+
difference between references and smart pointers is that references are a kind
33+
of pointer that only borrow data; by contrast, in many cases, smart pointers
34+
*own* the data that they point to.
35+
36+
We’ve actually already encountered a few smart pointers in this book, such as
37+
`String` and `Vec<T>` from Chapter 8, though we didn’t call them smart pointers
38+
at the time. Both these types count as smart pointers because they own some
39+
memory and allow you to manipulate it. They also have metadata (such as their
40+
capacity) and extra capabilities or guarantees (such as `String` ensuring its
41+
data will always be valid UTF-8).
42+
43+
<!-- Above: we said smart pointers don't own values earlier but in the
44+
paragraph above we're saying String and Vec own memory, is that a
45+
contradiction? -->
46+
<!-- Our original text read: "In Rust, an additional difference between plain
47+
references and smart pointers is that references are a kind of pointer that
48+
only borrow data; by contrast, in many cases, smart pointers *own* the data
49+
that they point to." You had edited this to say the opposite: "In Rust, smart
50+
pointers can only borrow data, whereas in many other languages, smart pointers
51+
*own* the data they point to." We had the "in rust" phrase not to distinguish
52+
Rust's smart pointer implementation from other languages' smart pointer
53+
implementations, but to acknowledge that the concept of borrowing and ownership
54+
doesn't apply in many languages. The distinction between references borrowing
55+
and smart pointers owning is important in the context of Rust. We've tried to
56+
clarify the sentence talking about C++ and separate it from the discussion of
57+
borrowing vs owning. So there shouldn't be a contradiction, and it should be
58+
clearer that smart pointers usually own the data they point to. /Carol -->
59+
60+
Smart pointers are usually implemented using structs. The characteristics that
61+
distinguish a smart pointer from an ordinary struct are that smart pointers
62+
implement the `Deref` and `Drop` traits. The `Deref` trait allows an instance
63+
of the smart pointer struct to behave like a reference so that we can write
64+
code that works with either references or smart pointers. The `Drop` trait
65+
allows us to customize the code that gets run when an instance of the smart
66+
pointer goes out of scope. In this chapter, we’ll be discussing both of those
67+
traits and demonstrating why they’re important to smart pointers.
2268

2369
Given that the smart pointer pattern is a general design pattern used
2470
frequently in Rust, this chapter won’t cover every smart pointer that exists.
25-
Many libraries have their own and you may write some yourself. The ones we
26-
cover here are the most common ones from the standard library:
71+
Many libraries have their own smart pointers and you can even write some
72+
yourself. We’ll just cover the most common smart pointers from the standard
73+
library:
74+
75+
<!-- Would it make sense to hyphenate reference-counted (and its derivations)
76+
here? I think that would be more clear, but I don't want to do that if that's
77+
not the Rust convention -->
78+
<!-- The hyphenated version doesn't appear to be a general convention to me, it
79+
looks like "reference counted" is most often not hyphenated. For example:
80+
http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf
81+
We'd be interested to know if there's a standard that we don't know about
82+
/Carol -->
2783

28-
* `Box<T>`, for allocating values on the heap
29-
* `Rc<T>`, a reference counted type so data can have multiple owners
30-
* `RefCell<T>`, which isn’t a smart pointer itself, but manages access to the
31-
smart pointers `Ref` and `RefMut` to enforce the borrowing rules at runtime
32-
instead of compile time
84+
* `Box<T>` for allocating values on the heap
85+
* `Rc<T>`, a reference counted type that enables multiple ownership
86+
* `Ref<T>` and `RefMut<T>`, accessed through `RefCell<T>`, a type that enforces
87+
the borrowing rules at runtime instead of compile time
3388

34-
Along the way, we’ll also cover:
89+
<!-- Should we add Ref and RefMut to this list, too? -->
90+
<!-- They were already sort of in the list; we've flipped the order to make it
91+
clearer /Carol-->
3592

36-
* The *interior mutability* pattern where an immutable type exposes an API for
37-
mutating an interior value, and the borrowing rules apply at runtime instead
38-
of compile time
39-
* Reference cycles, how they can leak memory, and how to prevent them
93+
Along the way, we’ll cover the *interior mutability* pattern where an immutable
94+
type exposes an API for mutating an interior value. We’ll also discuss
95+
*reference cycles*, how they can leak memory, and how to prevent them.
4096

4197
Let’s dive in!

0 commit comments

Comments
 (0)