Lesson 19 / 25
String Slices and Array Slices
&str versus String, &[T] versus Vec<T>.
Borrowed views
A slice is a borrowed view into contiguous data: &str into string data, &[T] into arrays or vectors. Functions that take &str accept both String (via &s) and literals, which is why it is the preferred parameter type. String slicing uses byte indices and must fall on character boundaries, or it panics; use chars() or char_indices() when working with characters.
Slices of strings and arrays, run
I ran this with Rust 1.99.0 (cargo run, edition 2024, standard library only). first_word works on a String and a literal; byte slicing gives "foun"; an array slice holds two elements; the first character of the Devanagari word is one char, and byte 1 is not a character boundary.
fn first_word(s: &str) -> &str { // &str works for String and literals
s.split(' ').next().unwrap_or("")
}
fn main() {
let owned = String::from("fountain pen");
let literal = "desk lamp";
println!("{} {}", first_word(&owned), first_word(literal));
let slice = &owned[0..4];
println!("slice: {slice}");
let nums = [10, 20, 30, 40];
let middle = &nums[1..3]; // array slice
println!("{middle:?} len {}", middle.len());
let word = "नमस्ते";
println!("first char: {:?}", word.chars().next());
println!("is char boundary at 1: {}", word.is_char_boundary(1));
}
Output:
fountain desk
slice: foun
[20, 30] len 2
first char: Some('न')
is char boundary at 1: falseAccept &str, return String
Taking &str makes functions flexible; returning String gives callers ownership without lifetime annotations.
Quick check: Why is &str preferred over &String as a parameter type?
- It owns the data
- It is mutable
- It is always faster to allocate
- It accepts both String values and string literals
Answer
It accepts both String values and string literals — More flexible borrowing.