Merge pull request #1025 from pduzinki/duplicate-listing-numbers

listing/figure numbering in chapter 15 corrected
This commit is contained in:
Carol (Nichols || Goulding)
2017-11-27 15:16:59 -05:00
committed by GitHub
4 changed files with 42 additions and 42 deletions

View File

@@ -35,7 +35,7 @@ for clean up? -->
this code gets run. It's hard to experience the cleaning up unless we print
something. /Carol -->
Listing 15-8 shows a `CustomSmartPointer` struct whose only custom
Listing 15-16 shows a `CustomSmartPointer` struct whose only custom
functionality is that it will print out `Dropping CustomSmartPointer!` when the
instance goes out of scope. This will demonstrate when Rust runs the `drop`
function:
@@ -69,7 +69,7 @@ fn main() {
}
```
<span class="caption">Listing 15-8: A `CustomSmartPointer` struct that
<span class="caption">Listing 15-16: A `CustomSmartPointer` struct that
implements the `Drop` trait, where we would put our clean up code.</span>
The `Drop` trait is included in the prelude, so we dont need to import it. We
@@ -122,7 +122,7 @@ up a value early. One example is when using smart pointers that manage locks;
you may want to force the `drop` method that releases the lock to run so that
other code in the same scope can acquire the lock. First, lets see what
happens if we try to call the `Drop` traits `drop` method ourselves by
modifying the `main` function from Listing 15-8 as shown in Listing 15-9:
modifying the `main` function from Listing 15-16 as shown in Listing 15-17:
<!-- Above: I'm not following why we are doing this, if it's not necessary and
we aren't going to cover it now anyway -- can you lay out why we're discussing
@@ -140,7 +140,7 @@ fn main() {
}
```
<span class="caption">Listing 15-9: Attempting to call the `drop` method from
<span class="caption">Listing 15-17: Attempting to call the `drop` method from
the `Drop` trait manually to clean up early</span>
If we try to compile this, well get this error:
@@ -171,7 +171,7 @@ force a value to be cleaned up early, we can use the `std::mem::drop` function.
The `std::mem::drop` function is different than the `drop` method in the `Drop`
trait. We call it by passing the value we want to force to be dropped early as
an argument. `std::mem::drop` is in the prelude, so we can modify `main` from
Listing 15-8 to call the `drop` function as shown in Listing 15-10:
Listing 15-16 to call the `drop` function as shown in Listing 15-18:
<span class="filename">Filename: src/main.rs</span>
@@ -194,7 +194,7 @@ fn main() {
}
```
<span class="caption">Listing 15-10: Calling `std::mem::drop` to explicitly
<span class="caption">Listing 15-18: Calling `std::mem::drop` to explicitly
drop a value before it goes out of scope</span>
Running this code will print the following:

View File

@@ -36,11 +36,11 @@ concurrency will cover how to do reference counting in multithreaded programs.
Lets return to our cons list example from Listing 15-6, as we defined it using
`Box<T>`. This time, we want to create two lists that both share ownership of a
third list, which conceptually will look something like Figure 15-11:
third list, which conceptually will look something like Figure 15-19:
<img alt="Two lists that share ownership of a third list" src="img/trpl15-03.svg" class="center" />
<span class="caption">Figure 15-11: Two lists, `b` and `c`, sharing ownership
<span class="caption">Figure 15-19: Two lists, `b` and `c`, sharing ownership
of a third list, `a`</span>
Well create list `a` that contains 5 and then 10, then make two more lists:
@@ -49,7 +49,7 @@ then continue on to the first `a` list containing 5 and 10. In other words,
both lists will try to share the first list containing 5 and 10.
Trying to implement this using our definition of `List` with `Box<T>` wont
work, as shown in Listing 15-12:
work, as shown in Listing 15-20:
<span class="filename">Filename: src/main.rs</span>
@@ -70,7 +70,7 @@ fn main() {
}
```
<span class="caption">Listing 15-12: Demonstrating were not allowed to have
<span class="caption">Listing 15-20: Demonstrating were not allowed to have
two lists using `Box<T>` that try to share ownership of a third list</span>
If we compile this, we get this error:
@@ -100,7 +100,7 @@ the list itself. The borrow checker wouldnt let us compile `let a = Cons(10,
`a` could take a reference to it.
Instead, well change our definition of `List` to use `Rc<T>` in place of
`Box<T>` as shown here in Listing 15-13. Each `Cons` variant now holds a value
`Box<T>` as shown here in Listing 15-21. Each `Cons` variant now holds a value
and an `Rc` pointing to a `List`. When we create `b`, instead of taking
ownership of `a`, we clone the `Rc` that `a` is holding, which increases the
number of references from 1 to 2 and lets `a` and `b` share ownership of the
@@ -133,7 +133,7 @@ fn main() {
}
```
<span class="caption">Listing 15-13: A definition of `List` that uses
<span class="caption">Listing 15-21: A definition of `List` that uses
`Rc<T>`</span>
We need to add a `use` statement to bring `Rc` into scope because its not in
@@ -154,7 +154,7 @@ memory.
### Cloning an `Rc<T>` Increases the Reference Count
Lets change our working example from Listing 15-13 so that we can see the
Lets change our working example from Listing 15-21 so that we can see the
reference counts changing as we create and drop references to the `Rc` in `a`.
<!-- Below -- can you let the reader know why we are doing this? What does it
@@ -162,7 +162,7 @@ show us/improve? Is this our working version of the code, or just illustrating
reference count? -->
<!-- This is illustrating reference counting /Carol -->
In Listing 15-14, well change `main` so that it has an inner scope around list
In Listing 15-22, well change `main` so that it has an inner scope around list
`c`, so that we can see how the reference count changes when `c` goes out of
scope. At each point in the program where the reference count changes, well
print out the reference count, which we can get by calling the
@@ -202,7 +202,7 @@ fn main() {
}
```
<span class="caption">Listing 15-14: Printing out the reference count</span>
<span class="caption">Listing 15-22: Printing out the reference count</span>
This will print out:

View File

@@ -156,7 +156,7 @@ mechanism for sending the messages: the application could choose to put a
message in the application, send an email, send a text message, or something
else. Our library doesnt need to know about that detail; all it needs is
something that implements a trait well provide called `Messenger`. Listing
15-15 shows our library code:
15-23 shows our library code:
<span class="filename">Filename: src/lib.rs</span>
@@ -197,7 +197,7 @@ impl<'a, T> LimitTracker<'a, T>
}
```
<span class="caption">Listing 15-15: A library to keep track of how close to a
<span class="caption">Listing 15-23: A library to keep track of how close to a
maximum value a value is, and warn when the value is at certain levels</span>
One important part of this code is that the `Messenger` trait has one method,
@@ -216,7 +216,7 @@ text message when we call `send`, will only keep track of the messages its
told to send. We can create a new instance of the mock object, create a
`LimitTracker` that uses the mock object, call the `set_value` method on
`LimitTracker`, then check that the mock object has the messages we expect.
Listing 15-16 shows an attempt of implementing a mock object to do just that,
Listing 15-24 shows an attempt of implementing a mock object to do just that,
but that the borrow checker wont allow:
<span class="filename">Filename: src/lib.rs</span>
@@ -254,7 +254,7 @@ mod tests {
}
```
<span class="caption">Listing 15-16: An attempt to implement a `MockMessenger`
<span class="caption">Listing 15-24: An attempt to implement a `MockMessenger`
that isnt allowed by the borrow checker</span>
This test code defines a `MockMessenger` struct that has a `sent_messages`
@@ -295,7 +295,7 @@ definition (feel free to try and see what error message you get).
This is where interior mutability can help! Were going to store the
`sent_messages` within a `RefCell`, and then the `send` message will be able to
modify `sent_messages` to store the messages weve seen. Listing 15-17 shows
modify `sent_messages` to store the messages weve seen. Listing 15-25 shows
what that looks like:
<span class="filename">Filename: src/lib.rs</span>
@@ -334,7 +334,7 @@ mod tests {
}
```
<span class="caption">Listing 15-17: Using `RefCell<T>` to be able to mutate an
<span class="caption">Listing 15-25: Using `RefCell<T>` to be able to mutate an
inner value while the outer value is considered immutable</span>
The `sent_messages` field is now of type `RefCell<Vec<String>>` instead of
@@ -376,8 +376,8 @@ mutable borrow at any point in time.
If we try to violate these rules, rather than getting a compiler error like we
would with references, the implementation of `RefCell<T>` will `panic!` at
runtime. Listing 15-18 shows a modification to the implementation of `send`
from Listing 15-17 where were deliberately trying to create two mutable
runtime. Listing 15-26 shows a modification to the implementation of `send`
from Listing 15-25 where were deliberately trying to create two mutable
borrows active for the same scope in order to illustrate that `RefCell<T>`
prevents us from doing this at runtime:
@@ -395,7 +395,7 @@ impl Messenger for MockMessenger {
}
```
<span class="caption">Listing 15-18: Creating two mutable references in the
<span class="caption">Listing 15-26: Creating two mutable references in the
same scope to see that `RefCell<T>` will panic</span>
We create a variable `one_borrow` for the `RefMut` smart pointer returned from
@@ -439,7 +439,7 @@ For example, recall the cons list example from Listing 15-13 where we used
`Rc<T>` to let us have multiple lists share ownership of another list. Because
`Rc<T>` only holds immutable values, we arent able to change any of the values
in the list once weve created them. Lets add in `RefCell<T>` to get the
ability to change the values in the lists. Listing 15-19 shows that by using a
ability to change the values in the lists. Listing 15-27 shows that by using a
`RefCell<T>` in the `Cons` definition, were allowed to modify the value stored
in all the lists:
@@ -472,7 +472,7 @@ fn main() {
}
```
<span class="caption">Listing 15-19: Using `Rc<RefCell<i32>>` to create a
<span class="caption">Listing 15-27: Using `Rc<RefCell<i32>>` to create a
`List` that we can mutate</span>
We create a value thats an instance of `Rc<RefCell<i32>` and store it in a

View File

@@ -13,7 +13,7 @@ never reach 0, and the values will never be dropped.
Lets take a look at how a reference cycle might happen and how to prevent it,
starting with the definition of the `List` enum and a `tail` method in Listing
15-20:
15-28:
<span class="filename">Filename: src/main.rs</span>
@@ -38,7 +38,7 @@ impl List {
}
```
<span class="caption">Listing 15-20: A cons list definition that holds a
<span class="caption">Listing 15-28: A cons list definition that holds a
`RefCell` so that we can modify what a `Cons` variant is referring to</span>
Were using another variation of the `List` definition from Listing 15-6. The
@@ -58,8 +58,8 @@ uses the definitions. We just broke these apart to avoid having a lot of code
and then a lot of explanation, I'd be fine having this be one big listing if
you think that would be better /Carol -->
In listing 15-21, were adding a `main` function that uses the definitions from
Listing 15-20. This code creates a list in `a`, a list in `b` that points to
In listing 15-29, were adding a `main` function that uses the definitions from
Listing 15-28. This code creates a list in `a`, a list in `b` that points to
the list in `a`, and then modifies the list in `a` to point to `b`, which
creates a reference cycle. There are `println!` statements along the way to
show what the reference counts are at various points in this process.
@@ -114,7 +114,7 @@ fn main() {
}
```
<span class="caption">Listing 15-21: Creating a reference cycle of two `List`
<span class="caption">Listing 15-29: Creating a reference cycle of two `List`
values pointing to each other</span>
We create an `Rc` instance holding a `List` value in the variable `a` with an
@@ -160,11 +160,11 @@ However, because `a` is still referencing the `Rc` that was in `b`, that `Rc`
has a count of 1 rather than 0, so the memory the `Rc` has on the heap wont be
dropped. The memory will just sit there with a count of one, forever.
To visualize this, weve created a reference cycle that looks like Figure 15-22:
To visualize this, weve created a reference cycle that looks like Figure 15-30:
<img alt="Reference cycle of lists" src="img/trpl15-04.svg" class="center" />
<span class="caption">Figure 15-22: A reference cycle of lists `a` and `b`
<span class="caption">Figure 15-30: A reference cycle of lists `a` and `b`
pointing to each other</span>
If you uncomment the last `println!` and run the program, Rust will try and
@@ -208,7 +208,7 @@ Another solution is reorganizing your data structures so that some references
express ownership and some references dont. In this way, we can have cycles
made up of some ownership relationships and some non-ownership relationships,
and only the ownership relationships affect whether a value may be dropped or
not. In Listing 15-20, we always want `Cons` variants to own their list, so
not. In Listing 15-28, we always want `Cons` variants to own their list, so
reorganizing the data structure isnt possible. Lets look at an example using
graphs made up of parent nodes and child nodes to see when non-ownership
relationships are an appropriate way to prevent reference cycles.
@@ -284,7 +284,7 @@ a `RefCell` in `children` around the `Vec`.
Next, lets use our struct definition and create one `Node` instance named
`leaf` with the value 3 and no children, and another instance named `branch`
with the value 5 and `leaf` as one of its children, as shown in Listing 15-23:
with the value 5 and `leaf` as one of its children, as shown in Listing 15-31:
<span class="filename">Filename: src/main.rs</span>
@@ -311,7 +311,7 @@ fn main() {
}
```
<span class="caption">Listing 15-23: Creating a `leaf` node with no children
<span class="caption">Listing 15-31: Creating a `leaf` node with no children
and a `branch` node with `leaf` as one of its children</span>
We clone the `Rc` in `leaf` and store that in `branch`, meaning the `Node` in
@@ -365,7 +365,7 @@ you think? It seems repetitive to explain this every time. /Carol
-->
This way, a node will be able to refer to its parent node, but does not own its
parent. In Listing 15-24, lets update `main` to use this new definition so
parent. In Listing 15-32, lets update `main` to use this new definition so
that the `leaf` node will have a way to refer to its parent, `branch`:
<!-- Why are we updating it, what are we doing here? Can you make that clear?
@@ -406,14 +406,14 @@ fn main() {
}
```
<span class="caption">Listing 15-24: A `leaf` node with a `Weak` reference to
<span class="caption">Listing 15-32: A `leaf` node with a `Weak` reference to
its parent node, `branch`</span>
<!-- Below: looks similar to what? What are we doing with this listing, can you
talk it through -->
Creating the `leaf` node looks similar to how creating the `leaf` node looked
in Listing 15-23, with the exception of the `parent` field: `leaf` starts out
in Listing 15-31, with the exception of the `parent` field: `leaf` starts out
without a parent, so we create a new, empty `Weak` reference instance.
At this point, when we try to get a reference to the parent of `leaf` by using
@@ -444,7 +444,7 @@ parent? -->
When we print out the parent of `leaf` again, this time well get a `Some`
variant holding `branch`: `leaf` can now access its parent! When we print out
`leaf`, we also avoid the cycle that eventually ended in a stack overflow like
we had in Listing 15-21: the `Weak` references are printed as `(Weak)`:
we had in Listing 15-29: the `Weak` references are printed as `(Weak)`:
```text
leaf parent = Some(Node { value: 5, parent: RefCell { value: (Weak) },
@@ -462,7 +462,7 @@ Lets look at how the `strong_count` and `weak_count` values of the `Rc`
instances change by creating a new inner scope and moving the creation of
`branch` into that scope. This will let us see what happens when `branch` is
created and then dropped when it goes out of scope. The modifications are shown
in Listing 15-25:
in Listing 15-33:
<span class="filename">Filename: src/main.rs</span>
@@ -510,7 +510,7 @@ fn main() {
}
```
<span class="caption">Listing 15-25: Creating `branch` in an inner scope and
<span class="caption">Listing 15-33: Creating `branch` in an inner scope and
examining strong and weak reference counts</span>
Once `leaf` is created, its `Rc` has a strong count of 1 and a weak count of 0.