Skip to content

Commit 969e8e8

Browse files
committed
Edit the traits section
1 parent eaddda3 commit 969e8e8

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

08_traits_and_reading_bytes.md

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,15 @@ The Version is `1` and the `bytes_slice` variable has been updated and no longer
6969
You may notice that the way this works is that you have to first create an array with a fixed size.
7070
Calling `read` will then extract the number of bytes equal to the size of the array, store that into a buffer and then update our slice.
7171

72-
## Traits Explanation
72+
## What are traits?
7373

74-
So what are traits exactly?
7574
Traits are a way to define shared behavior.
7675
You can think of them as a template for a particular set of behaviors.
7776
For example, the `Read` trait provides a template for types that want to "read data".
78-
It lays out what to expect and what types of functions are available.
77+
It lays out an *abstract interface* for a type: what kind of behavior is expected from the type and which functions are available to exercise that behavior.
7978

80-
Let's take a closer look at the `Read` trait [from the documentation](https://doc.rust-lang.org/std/io/trait.Read.html).
81-
It has a required method, `read`, which has the following function signature: `fn read(&mut self, buf: &mut [u8]) -> Result<usize>;`.
79+
Let's take a closer look at [the documentation for the `Read` trait](https://doc.rust-lang.org/std/io/trait.Read.html).
80+
It defines a required method, `read`, which has the following function signature: `fn read(&mut self, buf: &mut [u8]) -> Result<usize>;`.
8281

8382
```rust
8483
...
@@ -90,18 +89,19 @@ pub trait Read {
9089
...
9190
```
9291

93-
The `read` method itself is not actually implemented with any logic.
9492
You'll notice there's no function body, just the signature.
95-
The types that "implement" this trait are expected to provide the function logic for any *required* method, or trait methods that have no implementation.
93+
It means the `read` method itself is not actually implemented with any logic in the trait declaration.
94+
We expect the types that "implement" this trait to aactually provide the function logic for any *required* method, or trait methods, that have no implementation.
9695

9796
A trait can also provide other methods that a type can get access to once it has implemented the trait.
9897
These are known as *provided* methods and are considered *default* implementations since they can also be overwritten.
99-
You'll notice for example that there is a [`read_exact` method](https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact) which is implemented with a call to the [`default_read_exact`](https://doc.rust-lang.org/src/std/io/mod.rs.html#558) method.
98+
You'll notice, for example, that there is a [`read_exact` method](https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact) which is implemented with a call to the [`default_read_exact`](https://doc.rust-lang.org/src/std/io/mod.rs.html#558) method.
99+
`default_read_exact` by itself is implemented with a call the the `read` method.
100100

101101
As long as a type implements the `Read` trait by providing a `read` method, it will have access to these other *provided* methods.
102-
A type can also choose to override some or all of these *provided* methods as well and have its own implementations.
102+
A type can also choose to override some or all of these *provided* methods as well and have its own custom implementations (e.g. for performance reasons).
103103

104-
Now if we look at the `slice` type from the documentation, we can see that it [*implements* the `Read` trait](https://doc.rust-lang.org/std/primitive.slice.html#impl-Read-for-%26%5Bu8%5D) and provides the function logic for the `read` method.
104+
Now if we look at the `slice` type documentation, we can see that it [*implements* the `Read` trait](https://doc.rust-lang.org/std/primitive.slice.html#impl-Read-for-%26%5Bu8%5D) and provides the function logic for the `read` method.
105105
Let's take a look at [the source code](https://doc.rust-lang.org/src/std/io/impls.rs.html#235-250):
106106

107107
```rust
@@ -135,7 +135,7 @@ Simply notice how we *implement* a trait with the `impl` keyword.
135135
So `impl Read for &[u8]` is the code block that provides the function logic for the trait.
136136
The other thing to notice is how the function signature for `read` matches the trait's function signature.
137137

138-
The idea here is that different types, not just the `&[u8]` type can implement the `Read` trait by providing the function logic for any required method and then be expected to have similar behavior and get access to the trait's provided methods.
138+
The idea here is that different types, not just the `&[u8]` type can implement the `Read` trait by providing the function logic for any required method and then be expected to have similar behavior and get access to the trait's provided methods.
139139
The function logic itself for each type might differ, but given the template they are expected to take in the same arguments, return the same type and generally do the same thing, which in this case is to read some data and modify `self` and the buffer.
140140

141141
Again, you might notice some patterns in the code above that you are not yet familiar with, such as the `&mut` keyword and asterisk `*` before `self` at the bottom of the function.
@@ -152,7 +152,7 @@ fn read_version(transaction_hex: &str) -> u32 {
152152
let transaction_bytes = hex::decode(transaction_hex).unwrap();
153153
let mut bytes_slice = transaction_bytes.as_slice();
154154

155-
// Read contents of bytes_slice into a buffer.
155+
// Read contents of bytes_slice into a buffer
156156
let mut buffer = [0; 4];
157157
bytes_slice.read(&mut buffer).unwrap();
158158

@@ -165,15 +165,17 @@ fn main() {
165165
}
166166
```
167167

168-
And voila, this will print `Version: 1` as expected! Great job so far!
168+
And voila, this will print `Version: 1` as expected!
169+
Great job so far!
169170

170171
How do we grab the modified `bytes_slice` and continue decoding the transaction?
171172
What we probably want to do is pass in the `bytes_slice` into this function as an argument and continue using it in the `main` function.
172173
We'll talk more about that and associated Rust concepts of references and borrowing in the next section.
173174

174175
### Quiz
175176
1. *Take another look at the `Read` trait and the implementation of the `Read` trait for a slice in the documentation.
176-
What are the required and provided methods for the trait? What provided methods are being overwritten by the slice?*
177+
What are the required and provided methods for the trait?
178+
What provided methods are being overwritten by the slice?*
177179
2. *Consider the following block of code in which we create a Vec and then attempt to print it out:*
178180
```rust
179181
fn main() {

0 commit comments

Comments
 (0)