You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 07_arrays_and_conversions.md
+31-11Lines changed: 31 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,7 @@
1
1
# Arrays and Conversions
2
2
3
-
There's a simple method we can use on the `u32` data type called [`from_le_bytes`](https://doc.rust-lang.org/std/primitive.u32.html#method.from_le_bytes). This will convert a collection of bytes represented in little endian into an integer.
3
+
There's a simple method we can use on the `u32` data type called [`from_le_bytes`](https://doc.rust-lang.org/std/primitive.u32.html#method.from_le_bytes).
4
+
This will convert a collection of bytes represented in little endian into an integer.
This won't work unfortunately. We'll get a compiler error:
15
+
This won't work unfortunately.
16
+
We'll get a compiler error:
15
17
```shell
16
18
expected `[u8; 4]`, found `&[u8]`
17
19
```
18
20
19
-
If we look at the `from_le_bytes` method in the documentation and look at the function signature, we'll see that the parameter expected is of the type `[u8; 4]`. However, we're passing in a slice `&[u8]`. What is the difference between these two?
21
+
If we look at the `from_le_bytes` method in the documentation and check the function signature, we'll see that the parameter expected is of the type `[u8; 4]`.
22
+
However, we're passing in a slice `&[u8]`.
23
+
What is the difference between these two?
20
24
21
-
Well, in Rust, the data type `[T; N]` where `T` is any type and `N` is the number of elements, is called an *array*. Now we have to be careful because this is not the same as an array in other languages, such as Javascript and it's not the same as a list in Python. An array here is a fixed size collection that is stored on the stack as opposed to the heap. This means the data is available directly at runtime and no memory lookup is required to retrieve the data. An array's size is constant, cannot be changed and must be known and defined at compile time.
25
+
Well, in Rust, the data type `[T; N]` where `T` is any type and `N` is the number of elements, is called an *array*.
26
+
Now we have to be careful because this is not the same as an array in other languages, such as Javascript and it's not the same as a list in Python.
27
+
An array here is a fixed size collection that is stored on the stack as opposed to the heap.
28
+
This means the data is available more efficiently at runtime as there is no need to lookup that data on the heap with the use of a pointer.
29
+
An array's size is constant, cannot be changed and must be known and defined at compile time.
22
30
23
-
So the method `from_le_bytes` only works with arrays, which makes sense. It wants to be assured that it is only working with 4 bytes at compile time because that is exactly what is needed to create a `u32` integer on the stack. So how do we convert a slice to an array? One way is to initialize an array of 4 elements and then modify it by iterating over our slice and reading each value. But there's an easier way. Most primitive and standard data types implement the [`TryFrom`](https://doc.rust-lang.org/std/convert/trait.TryFrom.html) trait, which means they have methods which allow you to convert between types.
31
+
So the method `from_le_bytes` only works with arrays, which makes sense.
32
+
It wants to be assured that it is only working with 4 bytes at compile time because that is exactly what is needed to create a `u32` integer on the stack.
33
+
So how do we convert a slice to an array?
34
+
One way is to initialize an array of 4 elements and then modify it by iterating over our slice and reading each value.
35
+
But there's an easier way.
36
+
Most primitive and standard data types implement the [`TryFrom`](https://doc.rust-lang.org/std/convert/trait.TryFrom.html) trait, which means they have methods which allow you to convert between types.
24
37
25
38
So we can do something like the following:
26
39
```rust
27
40
<[u8; 4]>::try_from(&transaction_bytes[0..4])
28
41
```
29
42
30
-
Now remember, this method returns a `Result` type because the conversion could fail. So we need to handle that. We can do so by calling `unwrap` again.
43
+
Now remember, this method returns a `Result` type because the conversion could fail.
If a type implements the `TryFrom` it also provides a `try_into` method that can be used in the other direction. For example, we can also do something like this by being explicit about our variable's data type:
51
+
If a type implements the `TryFrom` it also provides a `try_into` method that can be used in the other direction.
52
+
For example, we can also do something like this by being explicit about our variable's data type:
If we run this, we'll get an error expecting the conversion type to be `&[u8; 4]` instead of `[u8; 4]`. This is because of the `&` in front of `transaction_bytes` which is incorrectly interpeted as a reference to everything that follows. What we need to do is ensure that it only refers to the slice. We'll add some parentheses:
69
+
If we run this, we'll get an error expecting the conversion type to be `&[u8; 4]` instead of `[u8; 4]`.
70
+
This is because of the `&` in front of `transaction_bytes` which is incorrectly interpeted as a reference to everything that follows.
71
+
What we need to do is ensure that it only refers to the slice.
0 commit comments