@@ -1,6 +1,6 @@
|
||||
# String slices
|
||||
|
||||
Throughout the previous chapters you've seen quite a few **string literals** being used in the code,
|
||||
Throughout the previous chapters you've seen quite a few **string literals** being used in the code,
|
||||
like `"To-Do"` or `"A ticket description"`.
|
||||
They were always followed by a call to `.to_string()` or `.into()`. It's time to understand why!
|
||||
|
||||
@@ -12,12 +12,12 @@ You define a string literal by enclosing the raw text in double quotes:
|
||||
let s = "Hello, world!";
|
||||
```
|
||||
|
||||
The type of `s` is `&str`, a **reference to a string slice**.
|
||||
The type of `s` is `&str`, a **reference to a string slice**.
|
||||
|
||||
## Memory layout
|
||||
|
||||
`&str` and `String` are different types—they're not interchangeable.
|
||||
Let's recall the memory layout of a `String` from our
|
||||
`&str` and `String` are different types—they're not interchangeable.\
|
||||
Let's recall the memory layout of a `String` from our
|
||||
[previous exploration](../03_ticket_v1/09_heap.md).
|
||||
If we run:
|
||||
|
||||
@@ -41,25 +41,25 @@ Heap: | H | e | l | l | o |
|
||||
+---+---+---+---+---+
|
||||
```
|
||||
|
||||
If you remember, we've [also examined](../03_ticket_v1/10_references_in_memory.md)
|
||||
If you remember, we've [also examined](../03_ticket_v1/10_references_in_memory.md)
|
||||
how a `&String` is laid out in memory:
|
||||
|
||||
```text
|
||||
--------------------------------------
|
||||
| |
|
||||
+----v----+--------+----------+ +----|----+
|
||||
| pointer | length | capacity | | pointer |
|
||||
| | | 5 | 5 | | |
|
||||
+----|----+--------+----------+ +---------+
|
||||
| s &s
|
||||
|
|
||||
v
|
||||
+---+---+---+---+---+
|
||||
| H | e | l | l | o |
|
||||
+---+---+---+---+---+
|
||||
--------------------------------------
|
||||
| |
|
||||
+----v----+--------+----------+ +----|----+
|
||||
| pointer | length | capacity | | pointer |
|
||||
| | | 5 | 5 | | |
|
||||
+----|----+--------+----------+ +---------+
|
||||
| s &s
|
||||
|
|
||||
v
|
||||
+---+---+---+---+---+
|
||||
| H | e | l | l | o |
|
||||
+---+---+---+---+---+
|
||||
```
|
||||
|
||||
`&String` points to the memory location where the `String`'s metadata is stored.
|
||||
`&String` points to the memory location where the `String`'s metadata is stored.\
|
||||
If we follow the pointer, we get to the heap-allocated data. In particular, we get to the first byte of the string, `H`.
|
||||
|
||||
What if we wanted a type that represents a **substring** of `s`? E.g. `ello` in `Hello`?
|
||||
@@ -100,19 +100,19 @@ Heap: | H | e | l | l | o | |
|
||||
- A pointer to the first byte of the slice.
|
||||
- The length of the slice.
|
||||
|
||||
`slice` doesn't own the data, it just points to it: it's a **reference** to the `String`'s heap-allocated data.
|
||||
`slice` doesn't own the data, it just points to it: it's a **reference** to the `String`'s heap-allocated data.\
|
||||
When `slice` is dropped, the heap-allocated data won't be deallocated, because it's still owned by `s`.
|
||||
That's why `slice` doesn't have a `capacity` field: it doesn't own the data, so it doesn't need to know how much
|
||||
That's why `slice` doesn't have a `capacity` field: it doesn't own the data, so it doesn't need to know how much
|
||||
space it was allocated for it; it only cares about the data it references.
|
||||
|
||||
## `&str` vs `&String`
|
||||
|
||||
As a rule of thumb, use `&str` rather than `&String` whenever you need a reference to textual data.
|
||||
As a rule of thumb, use `&str` rather than `&String` whenever you need a reference to textual data.\
|
||||
`&str` is more flexible and generally considered more idiomatic in Rust code.
|
||||
|
||||
If a method returns a `&String`, you're promising that there is heap-allocated UTF-8 text somewhere that
|
||||
**matches exactly** the one you're returning a reference to.
|
||||
If a method returns a `&str`, instead, you have a lot more freedom: you're just saying that *somewhere* there's a
|
||||
If a method returns a `&String`, you're promising that there is heap-allocated UTF-8 text somewhere that
|
||||
**matches exactly** the one you're returning a reference to.\
|
||||
If a method returns a `&str`, instead, you have a lot more freedom: you're just saying that _somewhere_ there's a
|
||||
bunch of text data and that a subset of it matches what you need, therefore you're returning a reference to it.
|
||||
|
||||
## References
|
||||
|
||||
Reference in New Issue
Block a user