You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/ch15-01-box.md
+29-29Lines changed: 29 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,11 +9,11 @@ Boxes don’t have performance overhead, other than storing their data on the
9
9
heap instead of on the stack. But they don’t have many extra capabilities
10
10
either. You’ll use them most often in these situations:
11
11
12
-
- When you have a type whose size can’t be known at compile time and you want
12
+
- When you have a type whose size can’t be known at compile time, and you want
13
13
to use a value of that type in a context that requires an exact size
14
-
- When you have a large amount of data and you want to transfer ownership but
15
-
ensure the data won’t be copied when you do so
16
-
- When you want to own a value and you care only that it’s a type that
14
+
- When you have a large amount of data, and you want to transfer ownership but
15
+
ensure that the data won’t be copied when you do so
16
+
- When you want to own a value, and you care only that it’s a type that
17
17
implements a particular trait rather than being of a specific type
18
18
19
19
We’ll demonstrate the first situation in [“Enabling Recursive Types with
@@ -23,9 +23,9 @@ because the data is copied around on the stack. To improve performance in this
23
23
situation, we can store the large amount of data on the heap in a box. Then,
24
24
only the small amount of pointer data is copied around on the stack, while the
25
25
data it references stays in one place on the heap. The third case is known as a
26
-
_trait object_, and [“Using Trait Objects That Allow for Values of Different
27
-
Types,”][trait-objects]<!-- ignore --> in Chapter 18 is devoted to that topic.
28
-
So what you learn here you’ll apply again in that section!
26
+
_trait object_, and [“Using Trait Objects to Abstract over Shared
27
+
Behavior”][trait-objects]<!-- ignore --> in Chapter 18 is devoted to that
28
+
topic. So, what you learn here you’ll apply again in that section!
29
29
30
30
<!-- Old headings. Do not remove or links may break. -->
31
31
@@ -69,10 +69,10 @@ types could theoretically continue infinitely, so Rust can’t know how much spa
69
69
the value needs. Because boxes have a known size, we can enable recursive types
70
70
by inserting a box in the recursive type definition.
71
71
72
-
As an example of a recursive type, let’s explore the _cons list_. This is a data
72
+
As an example of a recursive type, let’s explore the cons list. This is a data
73
73
type commonly found in functional programming languages. The cons list type
74
74
we’ll define is straightforward except for the recursion; therefore, the
75
-
concepts in the example we’ll work with will be useful any time you get into
75
+
concepts in the example we’ll work with will be useful anytime you get into
76
76
more complex situations involving recursive types.
77
77
78
78
<!-- Old headings. Do not remove or links may break. -->
@@ -96,11 +96,11 @@ list `1, 2, 3` with each pair in parentheses:
96
96
```
97
97
98
98
Each item in a cons list contains two elements: the value of the current item
99
-
and the next item. The last item in the list contains only a value called`Nil`
100
-
without a next item. A cons list is produced by recursively calling the`cons`
101
-
function. The canonical name to denote the base case of the recursion is`Nil`.
102
-
Note that this is not the same as the “null” or “nil” concept discussed in
103
-
Chapter 6, which is an invalid or absent value.
99
+
and of the next item. The last item in the list contains only a value called
100
+
`Nil`without a next item. A cons list is produced by recursively calling the
101
+
`cons`function. The canonical name to denote the base case of the recursion is
102
+
`Nil`. Note that this is not the same as the “null” or “nil” concept discussed
103
+
in Chapter 6, which is an invalid or absent value.
104
104
105
105
The cons list isn’t a commonly used data structure in Rust. Most of the time
106
106
when you have a list of items in Rust, `Vec<T>` is a better choice to use.
@@ -109,7 +109,7 @@ but by starting with the cons list in this chapter, we can explore how boxes
109
109
let us define a recursive data type without much distraction.
110
110
111
111
Listing 15-2 contains an enum definition for a cons list. Note that this code
112
-
won’t compile yet because the `List` type doesn’t have a known size, which
112
+
won’t compile yet, because the `List` type doesn’t have a known size, which
113
113
we’ll demonstrate.
114
114
115
115
<Listingnumber="15-2"file-name="src/main.rs"caption="The first attempt at defining an enum to represent a cons list data structure of `i32` values">
@@ -153,9 +153,9 @@ Listing 15-4.
153
153
</Listing>
154
154
155
155
The error shows this type “has infinite size.” The reason is that we’ve defined
156
-
`List` with a variant that is recursive: it holds another value of itself
156
+
`List` with a variant that is recursive: It holds another value of itself
157
157
directly. As a result, Rust can’t figure out how much space it needs to store a
158
-
`List` value. Let’s break down why we get this error. First we’ll look at how
158
+
`List` value. Let’s break down why we get this error. First, we’ll look at how
159
159
Rust decides how much space it needs to store a value of a non-recursive type.
160
160
161
161
#### Computing the Size of a Non-Recursive Type
@@ -183,7 +183,7 @@ type needs, the compiler looks at the variants, starting with the `Cons`
183
183
variant. The `Cons` variant holds a value of type `i32` and a value of type
184
184
`List`, and this process continues infinitely, as shown in Figure 15-1.
185
185
186
-
<imgalt="An infinite Cons list: a rectangle labeled 'Cons' split into two smaller rectangles. The first smaller rectangle holds the label 'i32', and the second smaller rectangle holds the label 'Cons' and a smaller version of the outer 'Cons' rectangle. The 'Cons' rectangles continue to hold smaller and smaller versions of themselves until the smallest comfortably-sized rectangle holds an infinity symbol, indicating that this repetition goes on forever"src="img/trpl15-01.svg"class="center"style="width: 50%;" />
186
+
<imgalt="An infinite Cons list: a rectangle labeled 'Cons' split into two smaller rectangles. The first smaller rectangle holds the label 'i32', an d the second smaller rectangle holds the label 'Cons' and a smaller version of the outer 'Cons' rectangle. The 'Cons' rectangles continue to hold sm aller and smaller versions of themselves until the smallest comfortablysized rectangle holds an infinity symbol, indicating that this repetition goes on forever."src="img/trpl15-01.svg"class="center"style="width: 50%;" />
187
187
188
188
<spanclass="caption">Figure 15-1: An infinite `List` consisting of infinite
189
189
`Cons` variants</span>
@@ -213,7 +213,7 @@ directly, we should change the data structure to store the value indirectly by
213
213
storing a pointer to the value instead.
214
214
215
215
Because a `Box<T>` is a pointer, Rust always knows how much space a `Box<T>`
216
-
needs: a pointer’s size doesn’t change based on the amount of data it’s
216
+
needs: A pointer’s size doesn’t change based on the amount of data it’s
217
217
pointing to. This means we can put a `Box<T>` inside the `Cons` variant instead
218
218
of another `List` value directly. The `Box<T>` will point to the next `List`
219
219
value that will be on the heap rather than inside the `Cons` variant.
@@ -224,25 +224,25 @@ rather than inside one another.
224
224
We can change the definition of the `List` enum in Listing 15-2 and the usage
225
225
of the `List` in Listing 15-3 to the code in Listing 15-5, which will compile.
226
226
227
-
<Listingnumber="15-5"file-name="src/main.rs"caption="Definition of `List` that uses `Box<T>` in order to have a known size">
227
+
<Listingnumber="15-5"file-name="src/main.rs"caption="The definition of `List` that uses `Box<T>` in order to have a known size">
The `Cons` variant needs the size of an `i32` plus the space to store the
236
-
box’s pointer data. The `Nil` variant stores no values, so it needs less space
237
-
on the stack than the `Cons` variant. We now know that any `List` value will
238
-
take up the size of an `i32` plus the size of a box’s pointer data. By using a
239
-
box, we’ve broken the infinite, recursive chain, so the compiler can figure out
240
-
the size it needs to store a `List` value. Figure 15-2 shows what the `Cons`
235
+
The `Cons` variant needs the size of an `i32` plus the space to store the box’s
236
+
pointer data. The `Nil` variant stores no values, so it needs less space on the
237
+
stack than the `Cons` variant. We now know that any `List` value will take up
238
+
the size of an `i32` plus the size of a box’s pointer data. By using a box,
239
+
we’ve broken the infinite, recursive chain, so the compiler can figure out the
240
+
size it needs to store a `List` value. Figure 15-2 shows what the `Cons`
241
241
variant looks like now.
242
242
243
-
<imgalt="A rectangle labeled 'Cons' split into two smaller rectangles. The first smaller rectangle holds the label 'i32', and the second smaller rectangle holds the label 'Box' with one inner rectangle that contains the label 'usize', representing the finite size of the box's pointer"src="img/trpl15-02.svg"class="center" />
243
+
<imgalt="A rectangle labeled 'Cons' split into two smaller rectangles. The first smaller rectangle holds the label 'i32', and the second smaller rectangle holds the label 'Box' with one inner rectangle that contains the label 'usize', representing the finite size of the box's pointer."src="img/trpl15-02.svg"class="center" />
244
244
245
-
<spanclass="caption">Figure 15-2: A `List` that is not infinitely sized
245
+
<spanclass="caption">Figure 15-2: A `List` that is not infinitely sized,
246
246
because `Cons` holds a `Box`</span>
247
247
248
248
Boxes provide only the indirection and heap allocation; they don’t have any
@@ -260,4 +260,4 @@ even more important to the functionality provided by the other smart pointer
260
260
types we’ll discuss in the rest of this chapter. Let’s explore these two traits
0 commit comments