Strings & Slices

String vs &str, UTF-8, slicing, splitting and parsing text.

Rust has two main string types. String owns a growable UTF-8 buffer on the heap. &str is a borrowed view into UTF-8 text — a string literal, or part of a String. Functions that only read text should take &str: it accepts both.

Working with text

push_str and += append to a String.

first_word returns &s[..i], a slice into the original text: nothing is copied.

'25°C' is 5 bytes but 4 characters: ° takes 2 bytes in UTF-8. len() counts bytes, chars().count() counts characters.

split, trim and split_once break a line into fields; unwrap is acceptable here because the input is known to be well-formed.

&samples[2..5] is a slice of an array: elements 2, 3 and 4.

Rules of thumb

let c = s[0]; // error: strings cannot be indexed by integer let c = s.chars().next(); // or s.as_bytes()[0] for the first byte

A UTF-8 character can be several bytes, so Rust does not allow indexing a string by position.

Why should a function take &str instead of &String?

&String converts to &str automatically, so &str accepts String references, string literals and slices — strictly more flexible.

Why is "°".len() equal to 2?

len() counts bytes, and ° is encoded as two bytes in UTF-8.