Skip to content

Commit

Permalink
The ones without number, caption, and file name
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmelos committed Sep 26, 2024
1 parent df49c42 commit d7c8e04
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/ch04-01-what-is-ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,14 @@ As a first example of ownership, we’ll look at the *scope* of some variables.
scope is the range within a program for which an item is valid. Take the
following variable:

<Listing>

```rust
let s = "hello";
```

</Listing>

The variable `s` refers to a string literal, where the value of the string is
hardcoded into the text of our program. The variable is valid from the point at
which it’s declared until the end of the current *scope*. Listing 4-1 shows a
Expand Down Expand Up @@ -156,10 +160,14 @@ data allocated on the heap and as such is able to store an amount of text that
is unknown to us at compile time. You can create a `String` from a string
literal using the `from` function, like so:

<Listing>

```rust
let s = String::from("hello");
```

</Listing>

The double colon `::` operator allows us to namespace this particular `from`
function under the `String` type rather than using some sort of name like
`string_from`. We’ll discuss this syntax more in the [“Method
Expand All @@ -169,10 +177,14 @@ Module Tree”][paths-module-tree]<!-- ignore --> in Chapter 7.

This kind of string *can* be mutated:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs:here}}
```

</Listing>

So, what’s the difference here? Why can `String` be mutated but literals
cannot? The difference is in how these two types deal with memory.

Expand Down Expand Up @@ -211,10 +223,14 @@ Rust takes a different path: the memory is automatically returned once the
variable that owns it goes out of scope. Here’s a version of our scope example
from Listing 4-1 using a `String` instead of a string literal:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs:here}}
```

</Listing>

There is a natural point at which we can return the memory our `String` needs
to the allocator: when `s` goes out of scope. When a variable goes out of
scope, Rust calls a special function for us. This function is called
Expand Down Expand Up @@ -256,10 +272,14 @@ onto the stack.

Now let’s look at the `String` version:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs:here}}
```

</Listing>

This looks very similar, so we might assume that the way it works would be the
same: that is, the second line would make a copy of the value in `s1` and bind
it to `s2`. But this isn’t quite what happens.
Expand Down Expand Up @@ -322,17 +342,25 @@ no longer valid. Therefore, Rust doesn’t need to free anything when `s1` goes
out of scope. Check out what happens when you try to use `s1` after `s2` is
created; it won’t work:

<Listing>

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs:here}}
```

</Listing>

You’ll get an error like this because Rust prevents you from using the
invalidated reference:

<Listing>

```console
{{#include ../listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt}}
```

</Listing>

If you’ve heard the terms *shallow copy* and *deep copy* while working with
other languages, the concept of copying the pointer, length, and capacity
without copying the data probably sounds like making a shallow copy. But
Expand Down Expand Up @@ -368,10 +396,14 @@ programming languages, you’ve probably seen them before.

Here’s an example of the `clone` method in action:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs:here}}
```

</Listing>

This works just fine and explicitly produces the behavior shown in Figure 4-3,
where the heap data *does* get copied.

Expand All @@ -384,10 +416,14 @@ different is going on.
There’s another wrinkle we haven’t talked about yet. This code using
integers—part of which was shown in Listing 4-2—works and is valid:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-06-copy/src/main.rs:here}}
```

</Listing>

But this code seems to contradict what we just learned: we don’t have a call to
`clone`, but `x` is still valid and wasn’t moved into `y`.

Expand Down
44 changes: 44 additions & 0 deletions src/ch04-02-references-and-borrowing.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,29 @@ s1`</span>
Let’s take a closer look at the function call here:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs:here}}
```

</Listing>

The `&s1` syntax lets us create a reference that *refers* to the value of `s1`
but does not own it. Because it does not own it, the value it points to will
not be dropped when the reference stops being used.

Likewise, the signature of the function uses `&` to indicate that the type of
the parameter `s` is a reference. Let’s add some explanatory annotations:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs:here}}
```

</Listing>

The scope in which the variable `s` is valid is the same as any function
parameter’s scope, but the value pointed to by the reference is not dropped
when `s` stops being used, because `s` doesn’t have ownership. When functions
Expand All @@ -79,10 +87,14 @@ Listing 4-6. Spoiler alert: it doesn’t work!

Here’s the error:

<Listing>

```console
{{#include ../listings/ch04-understanding-ownership/listing-04-06/output.txt}}
```

</Listing>

Just as variables are immutable by default, so are references. We’re not
allowed to modify something we have a reference to.

Expand Down Expand Up @@ -118,10 +130,14 @@ attempts to create two mutable references to `s` will fail:

Here’s the error:

<Listing>

```console
{{#include ../listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt}}
```

</Listing>

This error says that this code is invalid because we cannot borrow `s` as
mutable more than once at a time. The first mutable borrow is in `r1` and must
last until it’s used in the `println!`, but between the creation of that
Expand All @@ -146,23 +162,35 @@ refusing to compile code with data races!
As always, we can use curly brackets to create a new scope, allowing for
multiple mutable references, just not *simultaneous* ones:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs:here}}
```

</Listing>

Rust enforces a similar rule for combining mutable and immutable references.
This code results in an error:

<Listing>

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs:here}}
```

</Listing>

Here’s the error:

<Listing>

```console
{{#include ../listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt}}
```

</Listing>

Whew! We *also* cannot have a mutable reference while we have an immutable one
to the same value.

Expand All @@ -176,10 +204,14 @@ through the last time that reference is used. For instance, this code will
compile because the last usage of the immutable references, the `println!`,
occurs before the mutable reference is introduced:

<Listing>

```rust,edition2021
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs:here}}
```

</Listing>

The scopes of the immutable references `r1` and `r2` end after the `println!`
where they are last used, which is before the mutable reference `r3` is
created. These scopes don’t overlap, so this code is allowed: the compiler can
Expand Down Expand Up @@ -214,19 +246,27 @@ compile-time error:

Here’s the error:

<Listing>

```console
{{#include ../listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt}}
```

</Listing>

This error message refers to a feature we haven’t covered yet: lifetimes. We’ll
discuss lifetimes in detail in Chapter 10. But, if you disregard the parts
about lifetimes, the message does contain the key to why this code is a problem:

<Listing>

```text
this function's return type contains a borrowed value, but there is no value
for it to be borrowed from
```

</Listing>

Let’s take a closer look at exactly what’s happening at each stage of our
`dangle` code:

Expand All @@ -245,10 +285,14 @@ won’t let us do this.

The solution here is to return the `String` directly:

<Listing>

```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs:here}}
```

</Listing>

This works without any problems. Ownership is moved out, and nothing is
deallocated.

Expand Down
Loading

0 comments on commit d7c8e04

Please sign in to comment.