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.

The .. token in Rust is a context-dependent operator that serves four distinct syntactic and semantic roles: a range constructor in expressions, a range pattern in match arms, a struct update syntax (functional record update), and a rest pattern for destructuring.

1. Range Expressions

In an expression context, .. constructs a half-open interval (inclusive of the start, exclusive of the end). Depending on the presence or absence of operands, the compiler resolves the operator to one of four distinct types defined in the std::ops module.
  • start..end: Evaluates to std::ops::Range<Idx>. Requires both bounds.
  • start..: Evaluates to std::ops::RangeFrom<Idx>. Has a lower bound but no upper bound.
  • ..end: Evaluates to std::ops::RangeTo<Idx>. Has an upper bound but no lower bound.
  • ..: Evaluates to std::ops::RangeFull. Represents an unbounded range.
let range: std::ops::Range<i32> = 1..5;
let range_from: std::ops::RangeFrom<i32> = 1..;
let range_to: std::ops::RangeTo<i32> = ..5;
let range_full: std::ops::RangeFull = ..;

2. Range Patterns

In a pattern-matching context, .. constructs an exclusive range pattern. While visually identical to range expressions, range patterns are evaluated by the compiler as pattern-matching constructs rather than instantiating std::ops types. Rust strictly requires a lower bound for exclusive range patterns. Exclusive range-to patterns (..end) are not supported by the compiler; omitting a lower bound in a pattern requires the inclusive range operator (..=end).
  • start..end: Matches values greater than or equal to start and strictly less than end.
  • start..: Matches values greater than or equal to start.
let x = 3;
match x {
    1..5 => (), // Matches 1, 2, 3, 4
    10.. => (), // Matches 10 and above
    _ => (),    // Catch-all arm to ensure exhaustive matching
}

3. Struct Update Syntax

When instantiating a struct, .. acts as the base expression operator. It instructs the compiler to populate any unassigned fields in the new instance using the corresponding fields from an existing instance of the exact same type.
  • It must be the final element in the struct literal.
  • A trailing comma is strictly forbidden after the base expression (e.g., ..base_instance, produces a syntax error).
  • It adheres to standard Rust ownership rules: fields that do not implement the Copy trait are moved from the base expression into the new instance, rendering those specific fields in the base expression inaccessible.
struct MyStruct {
    field_a: i32,
    field_b: i32,
    field_c: i32,
}

let base_instance = MyStruct {
    field_a: 1,
    field_b: 2,
    field_c: 3,
};

let new_instance = MyStruct {
    field_a: 10,
    field_b: 20,
    ..base_instance
};

4. Rest Pattern (Destructuring)

In a destructuring context, .. functions as a “rest” or “ignore” token. It allows matching specific parts of a composite data type (tuples, slices, or structs) while explicitly discarding the remaining elements.
  • Structs: Ignores all unlisted fields.
  • Tuples and Slices: Matches zero or more elements. To prevent parsing ambiguity, the .. token can only be used exactly once within a single tuple or slice pattern.
struct Payload {
    id: u32,
    timestamp: u64,
    data: f64,
}

let instance = Payload {
    id: 101,
    timestamp: 1625097600,
    data: 42.0,
};

// Struct destructuring
let Payload { id, .. } = instance;

// Tuple destructuring
let (first, .., last) = (1, 2, 3, 4, 5);

// Slice destructuring
let [head, ..] = [10, 20, 30];
Master Rust with Deep Grasping Methodology!Learn More