Skip to content

Commit 10a2ae4

Browse files
committed
Break long paragraphs
1 parent af250c5 commit 10a2ae4

File tree

1 file changed

+50
-16
lines changed

1 file changed

+50
-16
lines changed

09_01_shared_references.md

+50-16
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# Shared References
22

3-
In addition to a *mutable* reference, as indicated by the `&mut` keyword, we can also pass around a *shared* reference to a variable, which can be done by simply prefacing a variable with the `&` symbol. A mutable reference can modify the underlying data where as the shared reference cannot and is read-only. We already saw an example of a shared reference in chapter 6 where we created a slice reference to data on the heap by prepending `[u8]` with the `&` symbol.
3+
In addition to a *mutable* reference, as indicated by the `&mut` keyword, we can also pass around a *shared* reference to a variable, which can be done by simply prefacing a variable with the `&` symbol.
4+
A mutable reference can modify the underlying data where as the shared reference cannot and is read-only.
5+
We already saw an example of a shared reference in chapter 6 where we created a slice reference to data on the heap by prepending `[u8]` with the `&` symbol.
46

5-
A reference is a kind of pointer. It points to some data elsewhere and "borrows" it instead of "owns" it. What does this mean? Well let's see with an [example](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#references-and-borrowing):
7+
A reference is a kind of pointer.
8+
It points to some data elsewhere and "borrows" it instead of "owns" it.
9+
What does this mean?
10+
Well let's see with an [example](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#references-and-borrowing):
611

712
```rust
813
fn main() {
@@ -18,7 +23,8 @@ fn calculate_length(s: String) -> usize {
1823
}
1924
```
2025

21-
You can run this code online with [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cf786ab3bacd43e260e73ae5efa49d50). If you run it, you'll notice that there will be a compiler error:
26+
You can run this code online with [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cf786ab3bacd43e260e73ae5efa49d50).
27+
If you run it, you'll notice that there will be a compiler error:
2228
```console
2329
Compiling playground v0.0.1 (/playground)
2430
error[E0382]: borrow of moved value: `s1`
@@ -34,11 +40,20 @@ error[E0382]: borrow of moved value: `s1`
3440
| ^^ value borrowed here after move
3541
```
3642

37-
The error points out that a move occurs and that we are unable to "borrow" the value after a move. It also mentions that the type, `String` does not implement the `Copy` trait.
43+
The error points out that a move occurs and that we are unable to "borrow" the value after a move.
44+
It also mentions that the type, `String` does not implement the `Copy` trait.
3845

39-
By default, any type that does not implement the `Copy` trait will get "moved" when passed as an argument. This means the variable that contains it will no longer be available within the scope of original function. It's "ownership" is now passed to the function being called, which in this case is `calculate_length`. Why does Rust do this? Well this has to do with how Rust handles memory management internally. This way, it's always clear which variable "owns" data so that when that variable goes out of scope, the memory associated with it can be automatically freed. This is different from how other languages handle memory with garbage collection or reference counting to know when memory should be freed.
46+
By default, any type that does not implement the `Copy` trait will get "moved" when passed as an argument.
47+
This means the variable that contains it will no longer be available within the scope of original function.
48+
It's "ownership" is now passed to the function being called, which in this case is `calculate_length`.
49+
Why does Rust do this?
50+
Well this has to do with how Rust handles memory management internally.
51+
This way, it's always clear which variable "owns" data so that when that variable goes out of scope, the memory associated with it can be automatically freed.
52+
This is different from how other languages handle memory with garbage collection or reference counting to know when memory should be freed.
4053

41-
So if we want to keep referring to the string after it has been passed to the `calculate_length` function, we need to use a *reference*. The reference will "borrow" the value and won't actually "own" the underlying data. This means that when the reference goes out of scope and is no longer in use, the heap data and its owner will still remain.
54+
So if we want to keep referring to the string after it has been passed to the `calculate_length` function, we need to use a *reference*.
55+
The reference will "borrow" the value and won't actually "own" the underlying data.
56+
This means that when the reference goes out of scope and is no longer in use, the heap data and its owner will still remain.
4257

4358
We can create a reference by placing the `&` symbol in front and modifying the function argument type:
4459

@@ -61,7 +76,10 @@ This will work now and correctly print:
6176
The length of 'hello' is 5.
6277
```
6378

64-
`s1` remains the owner of the String. `s` in the `calculate_length` will merely borrow a shared, immutable reference to the String. This means that we wouldn't be able to mutate the String in `calculate_length`. For example this won't work,
79+
`s1` remains the owner of the String.
80+
`s` in the `calculate_length` will merely borrow a shared, immutable reference to the String.
81+
This means that we wouldn't be able to mutate the String in `calculate_length`.
82+
For example this won't work,
6583

6684
```rust
6785
fn main() {
@@ -118,7 +136,8 @@ The length of 'hell' is 4.
118136

119137
That's the basics of shared and mutable references!
120138

121-
It's important to point out here that there is an exception to this rule, which we alluded to earlier and that is any type that implements the `Copy` trait, such as an integer type or an array `[u8; N]`. Typically, these are types that are stack allocated and don't require any heap allocations.
139+
It's important to point out here that there is an exception to this rule, which we alluded to earlier and that is any type that implements the `Copy` trait, such as an integer type or an array `[u8; N]`.
140+
Typically, these are types that are stack allocated and don't require any heap allocations.
122141

123142
Let's take a look at an example (see [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=bbc4ad315069566df4b5d853280492d1)):
124143

@@ -135,10 +154,13 @@ fn calculate_len(mut arr: [u8; 4]) -> usize {
135154
}
136155
```
137156

138-
This will run just fine without needing to pass a shared reference. Why? Because a copy will automatically be made in the `calculate_len` function and Rust won't have to worry about or think about ownership of data on the heap.
157+
This will run just fine without needing to pass a shared reference.
158+
Why? Because a copy will automatically be made in the `calculate_len` function and Rust won't have to worry about or think about ownership of data on the heap.
139159

140160
### Single Writer or Multiple Readers
141-
Rust enforces a simple, yet important rule when it comes to passing references and that is single writer OR multiple readers. In other words, you can have many different immutable, shared references to an object OR you can have just one mutable reference at any given time. You can't have both a shared reference and a mutable reference at the same time.
161+
Rust enforces a simple, yet important rule when it comes to passing references and that is single writer OR multiple readers.
162+
In other words, you can have many different immutable, shared references to an object OR you can have just one mutable reference at any given time.
163+
You can't have both a shared reference and a mutable reference at the same time.
142164

143165
Let's walk through an example to see why:
144166

@@ -150,9 +172,11 @@ fn main() {
150172
r[0] // r still points to v, which doesn't point to anything and so is a dangling pointer
151173
}
152174
```
153-
The statement `let aside = v` *moves* the vec from `v` into `aside`. However, `r` still references the variable `v` which is now uninitialized.
175+
The statement `let aside = v` *moves* the vec from `v` into `aside`.
176+
However, `r` still references the variable `v` which is now uninitialized.
154177

155-
If we have a shared reference to some variable and that variable goes out of scope or becomes uninitialized, we would end up with a dangling pointer. This can lead to unexpected behavior in a program and so Rust will attempt to avoid these possibilities.
178+
If we have a shared reference to some variable and that variable goes out of scope or becomes uninitialized, we would end up with a dangling pointer.
179+
This can lead to unexpected behavior in a program and so Rust will attempt to avoid these possibilities.
156180

157181
This is what the compiler will complain:
158182
```console
@@ -168,14 +192,24 @@ error[E0505]: cannot move out of `v` because it is borrowed
168192
17 | r[0]; // r still points to v, which doesn't point to anything and so is a dangling pointer
169193
| - borrow later used here
170194
```
171-
In other words, Rust will complain and enforce the rule that we cannot make any changes to `v` while it is being borrowed as an immutable, shared reference. This will prevent a case of a dangling pointer.
195+
In other words, Rust will complain and enforce the rule that we cannot make any changes to `v` while it is being borrowed as an immutable, shared reference.
196+
This will prevent a case of a dangling pointer.
172197

173-
You may see this compiler error from time to time. Just remember the rule: you can only have a single writer (mutable reference) OR multiple readers (shared references).
198+
You may see this compiler error from time to time.
199+
Just remember the rule: you can only have a single writer (mutable reference) OR multiple readers (shared references).
174200

175-
Ok! That's it for references! Take a breather as you just got past one of the hardest aspects of understanding the Rust programmming language. Don't worry if it hasn't fully "sunk in" yet. This is something that takes time and practice to get familiar with. Just know that with time these concepts will make more sense and you might even begin to start appreciating them.
201+
Ok! That's it for references!
202+
Take a breather as you just got past one of the hardest aspects of understanding the Rust programmming language.
203+
Don't worry if it hasn't fully "sunk in" yet.
204+
This is something that takes time and practice to get familiar with.
205+
Just know that with time these concepts will make more sense and you might even begin to start appreciating them.
176206

177207
### Quiz
178-
*What do you think would happen if we attempted to modify the vector in our project while we have a slice that borrows a reference to it? Experiment by calling `.clear()` on the vector (after declaring it mutable). See example below. Run it and see what happens. Can you explain why the compiler is returning an error and the meaning of that error?*
208+
*What do you think would happen if we attempted to modify the vector in our project while we have a slice that borrows a reference to it?
209+
Experiment by calling `.clear()` on the vector (after declaring it mutable).
210+
See example below.
211+
Run it and see what happens.
212+
Can you explain why the compiler is returning an error and the meaning of that error?*
179213
```rust
180214
fn main() {
181215
let transaction_hex = "010000000242d5c1d6f7308bbe95c0f6e1301dd73a8da77d2155b0773bc297ac47f9cd7380010000006a4730440220771361aae55e84496b9e7b06e0a53dd122a1425f85840af7a52b20fa329816070220221dd92132e82ef9c133cb1a106b64893892a11acf2cfa1adb7698dcdc02f01b0121030077be25dc482e7f4abad60115416881fe4ef98af33c924cd8b20ca4e57e8bd5feffffff75c87cc5f3150eefc1c04c0246e7e0b370e64b17d6226c44b333a6f4ca14b49c000000006b483045022100e0d85fece671d367c8d442a96230954cdda4b9cf95e9edc763616d05d93e944302202330d520408d909575c5f6976cc405b3042673b601f4f2140b2e4d447e671c47012103c43afccd37aae7107f5a43f5b7b223d034e7583b77c8cd1084d86895a7341abffeffffff02ebb10f00000000001976a9144ef88a0b04e3ad6d1888da4be260d6735e0d308488ac508c1e000000000017a91476c0c8f2fc403c5edaea365f6a284317b9cdf7258700000000";

0 commit comments

Comments
 (0)