Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A slice pattern is a structural pattern matching mechanism in Rust used to destructure and match against contiguous sequences of elements, specifically arrays ([T; N]) and dynamically sized slices (&[T]). Vectors (Vec<T>) cannot be matched directly using slice patterns; they must first be borrowed or dereferenced into a slice (e.g., &v[..] or v.as_slice()). The pattern evaluates the sequence based on its length, the values of specific elements, or a combination of both, allowing for precise extraction of elements and subslices.

Core Syntax and Mechanics

Slice patterns are enclosed in square brackets [] and can contain literal values, variable bindings, wildcards (_), and the rest pattern (..).

Exact Length Matching

You can match a sequence of a specific, known length. If the sequence length does not match the pattern length, the match arm fails.
let slice: &[i32] = &[10, 20, 30];

match slice {
    [10, x, 30] => println!("Matched exact length. Middle element is {}", x),
    [a, b, c] => println!("Matched any three elements: {}, {}, {}", a, b, c),
    _ => println!("Did not match a three-element slice"),
}

The Rest Pattern (..)

The .. token represents a variable-length sequence of elements. It allows you to match the beginning, the end, or both ends of a slice while ignoring the remaining elements. Rule: The .. token can only be used once per slice pattern. Using it multiple times (e.g., [1, .., 2, ..]) results in a compiler error due to ambiguity.
let slice: &[i32] = &[1, 2, 3, 4, 5];

match slice {
    [1, .., 5] => println!("Matches starting with 1 and ending with 5. Middle is ignored."),
    [.., 4, 5] => println!("Matches ending with 4 and 5. Beginning is ignored."),
    [1, 2, ..] => println!("Matches starting with 1 and 2. End is ignored."),
    [..] => println!("Matches a slice of any length."),
}

Subslice Binding (@ ..)

You can capture the elements matched by the rest pattern into a new variable using the @ binding operator. The resulting bound variable will be a slice (&[T]) containing the captured elements. To illustrate how bindings are evaluated without shadowing or unreachable arms, consider these distinct match statements:
let slice: &[i32] = &[1, 2, 3, 4, 5];

// Example 1: Extracting the middle elements
match slice {
    [first, middle @ .., last] => {
        // first is bound to &1
        // middle is bound to &[2, 3, 4]
        // last is bound to &5
    }
    _ => ()
}

// Example 2: Extracting all but the last element
match slice {
    [head @ .., tail] => {
        // head is bound to &[1, 2, 3, 4]
        // tail is bound to &5
    }
    _ => ()
}

Technical Nuances

Exhaustiveness Checking When matching against a dynamically sized slice (&[T]), the compiler cannot know the length of the slice at compile time. Therefore, slice patterns on &[T] are inherently non-exhaustive unless they include a catch-all arm (_) or an unconditional rest pattern ([..]). Conversely, when matching against a fixed-size array ([T; N]), the compiler knows the exact length. You can write exhaustive matches without a catch-all if you cover all possible value permutations for that specific length. Match Ergonomics and Binding Modes When you match a reference to a slice (&[T]), Rust’s match ergonomics automatically dereference the slice and bind the individual elements by reference (&T).
let arr = [String::from("A"), String::from("B")];
let slice: &[String] = &arr;

match slice {
    // 'a' and 'b' are inferred as &String, not String.
    // This prevents moving out of a borrowed context.
    [a, b] => {} 
    _ => {}
}
If you match an owned array ([T; N]) directly, the elements are moved into the bindings unless explicitly prefixed with ref.
let arr = [String::from("A"), String::from("B")];

match arr {
    // 'a' and 'b' take ownership of the Strings. 'arr' is consumed.
    [a, b] => {} 
}
Master Rust with Deep Grasping Methodology!Learn More