Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use <Listing> for Chapter 15 #4072

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions src/ch15-01-box.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,13 @@ syntax and how to interact with values stored within a `Box<T>`.

Listing 15-1 shows how to use a box to store an `i32` value on the heap:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-1" file-name="src/main.rs" caption="Storing an `i32` value on the heap using a box">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-01/src/main.rs}}
```

<span class="caption">Listing 15-1: Storing an `i32` value on the heap using a
box</span>
</Listing>

We define the variable `b` to have the value of a `Box` that points to the
value `5`, which is allocated on the heap. This program will print `b = 5`; in
Expand Down Expand Up @@ -106,14 +105,13 @@ Listing 15-2 contains an enum definition for a cons list. Note that this code
won’t compile yet because the `List` type doesn’t have a known size, which
we’ll demonstrate.

<span class="filename">Filename: src/main.rs</span>
<Listing number="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">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-02/src/main.rs:here}}
```

<span class="caption">Listing 15-2: The first attempt at defining an enum to
represent a cons list data structure of `i32` values</span>
</Listing>

> Note: We’re implementing a cons list that holds only `i32` values for the
> purposes of this example. We could have implemented it using generics, as we
Expand All @@ -123,14 +121,13 @@ represent a cons list data structure of `i32` values</span>
Using the `List` type to store the list `1, 2, 3` would look like the code in
Listing 15-3:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-3" file-name="src/main.rs" caption="Using the `List` enum to store the list `1, 2, 3`">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-03/src/main.rs:here}}
```

<span class="caption">Listing 15-3: Using the `List` enum to store the list `1,
2, 3`</span>
</Listing>

The first `Cons` value holds `1` and another `List` value. This `List` value is
another `Cons` value that holds `2` and another `List` value. This `List` value
Expand All @@ -140,12 +137,13 @@ is one more `Cons` value that holds `3` and a `List` value, which is finally
If we try to compile the code in Listing 15-3, we get the error shown in
Listing 15-4:

<Listing number="15-4" file-name="output.txt" caption="The error we get when attempting to define a recursive enum">

```console
{{#include ../listings/ch15-smart-pointers/listing-15-03/output.txt}}
```

<span class="caption">Listing 15-4: The error we get when attempting to define
a recursive enum</span>
</Listing>

The error shows this type “has infinite size.” The reason is that we’ve defined
`List` with a variant that is recursive: it holds another value of itself
Expand Down Expand Up @@ -215,14 +213,13 @@ rather than inside one another.
We can change the definition of the `List` enum in Listing 15-2 and the usage
of the `List` in Listing 15-3 to the code in Listing 15-5, which will compile:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-5" file-name="src/main.rs" caption="Definition of `List` that uses `Box<T>` in order to have a known size">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-05/src/main.rs}}
```

<span class="caption">Listing 15-5: Definition of `List` that uses `Box<T>` in
order to have a known size</span>
</Listing>

The `Cons` variant needs the size of an `i32` plus the space to store the
box’s pointer data. The `Nil` variant stores no values, so it needs less space
Expand Down
38 changes: 16 additions & 22 deletions src/ch15-02-deref.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,13 @@ as an arrow to a value stored somewhere else. In Listing 15-6, we create a
reference to an `i32` value and then use the dereference operator to follow the
reference to the value:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-6" file-name="src/main.rs" caption="Using the dereference operator to follow a reference to an `i32` value">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-06/src/main.rs}}
```

<span class="caption">Listing 15-6: Using the dereference operator to follow a
reference to an `i32` value</span>
</Listing>

The variable `x` holds an `i32` value `5`. We set `y` equal to a reference to
`x`. We can assert that `x` is equal to `5`. However, if we want to make an
Expand All @@ -63,14 +62,13 @@ reference; the dereference operator used on the `Box<T>` in Listing 15-7
functions in the same way as the dereference operator used on the reference in
Listing 15-6:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-7" file-name="src/main.rs" caption="Using the dereference operator on a `Box<i32>`">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-07/src/main.rs}}
```

<span class="caption">Listing 15-7: Using the dereference operator on a
`Box<i32>`</span>
</Listing>

The main difference between Listing 15-7 and Listing 15-6 is that here we set
`y` to be an instance of a `Box<T>` pointing to a copied value of `x` rather
Expand All @@ -91,13 +89,13 @@ The `Box<T>` type is ultimately defined as a tuple struct with one element, so
Listing 15-8 defines a `MyBox<T>` type in the same way. We’ll also define a
`new` function to match the `new` function defined on `Box<T>`.

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-8" file-name="src/main.rs" caption="Defining a `MyBox<T>` type">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-08/src/main.rs:here}}
```

<span class="caption">Listing 15-8: Defining a `MyBox<T>` type</span>
</Listing>

We define a struct named `MyBox` and declare a generic parameter `T`, because
we want our type to hold values of any type. The `MyBox` type is a tuple struct
Expand All @@ -109,14 +107,13 @@ changing it to use the `MyBox<T>` type we’ve defined instead of `Box<T>`. The
code in Listing 15-9 won’t compile because Rust doesn’t know how to dereference
`MyBox`.

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-9" file-name="src/main.rs" caption="Attempting to use `MyBox<T>` in the same way we used references and `Box<T>`">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-09/src/main.rs:here}}
```

<span class="caption">Listing 15-9: Attempting to use `MyBox<T>` in the same
way we used references and `Box<T>`</span>
</Listing>

Here’s the resulting compilation error:

Expand All @@ -137,13 +134,13 @@ by the standard library, requires us to implement one method named `deref` that
borrows `self` and returns a reference to the inner data. Listing 15-10
contains an implementation of `Deref` to add to the definition of `MyBox`:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-10" file-name="src/main.rs" caption="Implementing `Deref` on `MyBox<T>`">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-10/src/main.rs:here}}
```

<span class="caption">Listing 15-10: Implementing `Deref` on `MyBox<T>`</span>
</Listing>

The `type Target = T;` syntax defines an associated type for the `Deref`
trait to use. Associated types are a slightly different way of declaring a
Expand Down Expand Up @@ -210,27 +207,25 @@ Listing 15-8 as well as the implementation of `Deref` that we added in Listing
15-10. Listing 15-11 shows the definition of a function that has a string slice
parameter:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-11" file-name="src/main.rs" caption="A `hello` function that has the parameter `name` of type `&str`">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-11/src/main.rs:here}}
```

<span class="caption">Listing 15-11: A `hello` function that has the parameter
`name` of type `&str`</span>
</Listing>

We can call the `hello` function with a string slice as an argument, such as
`hello("Rust");` for example. Deref coercion makes it possible to call `hello`
with a reference to a value of type `MyBox<String>`, as shown in Listing 15-12:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-12" file-name="src/main.rs" caption="Calling `hello` with a reference to a `MyBox<String>` value, which works because of deref coercion">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-12/src/main.rs:here}}
```

<span class="caption">Listing 15-12: Calling `hello` with a reference to a
`MyBox<String>` value, which works because of deref coercion</span>
</Listing>

Here we’re calling the `hello` function with the argument `&m`, which is a
reference to a `MyBox<String>` value. Because we implemented the `Deref` trait
Expand All @@ -244,14 +239,13 @@ If Rust didn’t implement deref coercion, we would have to write the code in
Listing 15-13 instead of the code in Listing 15-12 to call `hello` with a value
of type `&MyBox<String>`.

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-13" file-name="src/main.rs" caption="The code we would have to write if Rust didn’t have deref coercion">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-13/src/main.rs:here}}
```

<span class="caption">Listing 15-13: The code we would have to write if Rust
didn’t have deref coercion</span>
</Listing>

The `(*m)` dereferences the `MyBox<String>` into a `String`. Then the `&` and
`[..]` take a string slice of the `String` that is equal to the whole string to
Expand Down
15 changes: 6 additions & 9 deletions src/ch15-03-drop.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@ Listing 15-14 shows a `CustomSmartPointer` struct whose only custom
functionality is that it will print `Dropping CustomSmartPointer!` when the
instance goes out of scope, to show when Rust runs the `drop` function.

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-14" file-name="src/main.rs" caption="A `CustomSmartPointer` struct that implements the `Drop` trait where we would put our cleanup code">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-14/src/main.rs}}
```

<span class="caption">Listing 15-14: A `CustomSmartPointer` struct that
implements the `Drop` trait where we would put our cleanup code</span>
</Listing>

The `Drop` trait is included in the prelude, so we don’t need to bring it into
scope. We implement the `Drop` trait on `CustomSmartPointer` and provide an
Expand Down Expand Up @@ -79,14 +78,13 @@ If we try to call the `Drop` trait’s `drop` method manually by modifying the
`main` function from Listing 15-14, as shown in Listing 15-15, we’ll get a
compiler error:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-15" file-name="src/main.rs" caption="Attempting to call the `drop` method from the `Drop` trait manually to clean up early">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-15/src/main.rs:here}}
```

<span class="caption">Listing 15-15: Attempting to call the `drop` method from
the `Drop` trait manually to clean up early</span>
</Listing>

When we try to compile this code, we’ll get this error:

Expand Down Expand Up @@ -114,14 +112,13 @@ trait. We call it by passing as an argument the value we want to force drop.
The function is in the prelude, so we can modify `main` in Listing 15-15 to
call the `drop` function, as shown in Listing 15-16:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-16" file-name="src/main.rs" caption="Calling `std::mem::drop` to explicitly drop a value before it goes out of scope">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-16/src/main.rs:here}}
```

<span class="caption">Listing 15-16: Calling `std::mem::drop` to explicitly
drop a value before it goes out of scope</span>
</Listing>

Running this code will print the following:

Expand Down
14 changes: 6 additions & 8 deletions src/ch15-04-rc.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ words, both lists will share the first list containing 5 and 10.
Trying to implement this scenario using our definition of `List` with `Box<T>`
won’t work, as shown in Listing 15-17:

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-17" file-name="src/main.rs" caption="Demonstrating we’re not allowed to have two lists using `Box<T>` that try to share ownership of a third list">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-17/src/main.rs}}
```

<span class="caption">Listing 15-17: Demonstrating we’re not allowed to have
two lists using `Box<T>` that try to share ownership of a third list</span>
</Listing>

When we compile this code, we get this error:

Expand Down Expand Up @@ -84,14 +83,13 @@ we call `Rc::clone`, the reference count to the data within the `Rc<List>` will
increase, and the data won’t be cleaned up unless there are zero references to
it.

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-18" file-name="src/main.rs" caption="A definition of `List` that uses `Rc<T>`">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-18/src/main.rs}}
```

<span class="caption">Listing 15-18: A definition of `List` that uses
`Rc<T>`</span>
</Listing>

We need to add a `use` statement to bring `Rc<T>` into scope because it’s not
in the prelude. In `main`, we create the list holding 5 and 10 and store it in
Expand All @@ -118,13 +116,13 @@ counts changing as we create and drop references to the `Rc<List>` in `a`.
In Listing 15-19, we’ll change `main` so it has an inner scope around list `c`;
then we can see how the reference count changes when `c` goes out of scope.

<span class="filename">Filename: src/main.rs</span>
<Listing number="15-19" file-name="src/main.rs" caption="Printing the reference count">

```rust
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-19/src/main.rs:here}}
```

<span class="caption">Listing 15-19: Printing the reference count</span>
</Listing>

At each point in the program where the reference count changes, we print the
reference count, which we get by calling the `Rc::strong_count` function. This
Expand Down
Loading