8.5 Slices as Parameters and Return Types

Slices allow functions to work with portions of collections without taking ownership.

8.5.1 String Slices

Passing String Slices to Functions

fn print_slice(s: &str) {
    println!("Slice: {}", s);
}

fn main() {
    let s = String::from("Hello, world!");
    print_slice(&s[7..12]); // Passes "world"
    print_slice(&s);        // Passes the entire string
    print_slice("Hello");   // String literals are &str
}
  • Functions that take &str can accept both string slices and string literals.

Returning String Slices

Returning slices requires careful handling of lifetimes to ensure safety.

fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[..i];
        }
    }
    &s
}

fn main() {
    let s = String::from("Hello world");
    let word = first_word(&s);
    println!("First word: {}", word);
}
  • The first_word function returns a slice of the input string.

8.5.2 Array Slices

Passing Array Slices to Functions

fn sum(slice: &[i32]) -> i32 {
    slice.iter().sum()
}
fn main() {
    let arr = [1, 2, 3, 4, 5];
    let total = sum(&arr);
    println!("Total sum: {}", total);
}
  • The function sum takes a slice of integers and returns their sum.

8.5.3 Slices with Vectors

Vectors are resizable arrays in Rust. You can create slices from vectors as well.

fn print_vector_slice(v: &[i32]) {
    for item in v {
        println!("{}", item);
    }
}
fn main() {
    let v = vec![10, 20, 30, 40, 50];
    print_vector_slice(&v[1..4]); // Prints 20, 30, 40
}
  • Slices work uniformly across arrays and vectors.