<span class="filename">Filename: src/main.rs</span>
```rust
-fn first_word(s: &String) -> usize {
- let bytes = s.as_bytes();
-
- for (i, &item) in bytes.iter().enumerate() {
- if item == b' ' {
- return i;
- }
- }
-
- s.len()
-}
+{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:here}}
```
<span class="caption">Listing 4-7: The `first_word` function that returns a
`as_bytes` method:
```rust,ignore
-let bytes = s.as_bytes();
+{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:as_bytes}}
```
Next, we create an iterator over the array of bytes using the `iter` method:
```rust,ignore
-for (i, &item) in bytes.iter().enumerate() {
+{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:iter}}
```
We’ll discuss iterators in more detail in Chapter 13. For now, know that `iter`
Otherwise, we return the length of the string by using `s.len()`:
```rust,ignore
- if item == b' ' {
- return i;
- }
-}
-
-s.len()
+{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:inside_for}}
```
We now have a way to find out the index of the end of the first word in the
<span class="filename">Filename: src/main.rs</span>
```rust
-# fn first_word(s: &String) -> usize {
-# let bytes = s.as_bytes();
-#
-# for (i, &item) in bytes.iter().enumerate() {
-# if item == b' ' {
-# return i;
-# }
-# }
-#
-# s.len()
-# }
-#
-fn main() {
- let mut s = String::from("hello world");
-
- let word = first_word(&s); // word will get the value 5
-
- s.clear(); // this empties the String, making it equal to ""
-
- // word still has the value 5 here, but there's no more string that
- // we could meaningfully use the value 5 with. word is now totally invalid!
-}
+{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-08/src/main.rs:here}}
```
<span class="caption">Listing 4-8: Storing the result from calling the
A *string slice* is a reference to part of a `String`, and it looks like this:
```rust
-let s = String::from("hello world");
-
-let hello = &s[0..5];
-let world = &s[6..11];
+{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs:here}}
```
This is similar to taking a reference to the whole `String` but with the extra
<span class="filename">Filename: src/main.rs</span>
```rust
-fn first_word(s: &String) -> &str {
- let bytes = s.as_bytes();
-
- for (i, &item) in bytes.iter().enumerate() {
- if item == b' ' {
- return &s[0..i];
- }
- }
-
- &s[..]
-}
+{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs:here}}
```
We get the index for the end of the word in the same way as we did in Listing
<span class="filename">Filename: src/main.rs</span>
```rust,ignore,does_not_compile
-fn main() {
- let mut s = String::from("hello world");
-
- let word = first_word(&s);
-
- s.clear(); // error!
-
- println!("the first word is: {}", word);
-}
+{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs:here}}
```
Here’s the compiler error:
```text
-error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
- --> src/main.rs:18:5
- |
-16 | let word = first_word(&s);
- | -- immutable borrow occurs here
-17 |
-18 | s.clear(); // error!
- | ^^^^^^^^^ mutable borrow occurs here
-19 |
-20 | println!("the first word is: {}", word);
- | ---- immutable borrow later used here
+{{#include ../listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt}}
```
Recall from the borrowing rules that if we have an immutable reference to
and `&str` values.
```rust,ignore
-fn first_word(s: &str) -> &str {
+{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-09/src/main.rs:here}}
```
<span class="caption">Listing 4-9: Improving the `first_word` function by using
<span class="filename">Filename: src/main.rs</span>
```rust
-# fn first_word(s: &str) -> &str {
-# let bytes = s.as_bytes();
-#
-# for (i, &item) in bytes.iter().enumerate() {
-# if item == b' ' {
-# return &s[0..i];
-# }
-# }
-#
-# &s[..]
-# }
-fn main() {
- let my_string = String::from("hello world");
-
- // first_word works on slices of `String`s
- let word = first_word(&my_string[..]);
-
- let my_string_literal = "hello world";
-
- // first_word works on slices of string literals
- let word = first_word(&my_string_literal[..]);
-
- // Because string literals *are* string slices already,
- // this works too, without the slice syntax!
- let word = first_word(my_string_literal);
-}
+{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-09/src/main.rs:usage}}
```
### Other Slices