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 Rust array is a homogeneous, fixed-size collection of elements stored in contiguous memory. Its length is determined at compile time and forms an intrinsic part of its type signature, meaning an array cannot grow or shrink during runtime. By default, arrays are allocated on the stack.

Type Signature

The type signature of an array is written as [T; N]:
  • T represents the data type of the elements. All elements must be of this exact type.
  • N represents the length of the array. It must be a compile-time constant expression of type usize.
Because N is part of the type, [i32; 3] and [i32; 4] are entirely distinct and incompatible types in Rust.

Initialization Syntax

Arrays can be initialized using two primary syntaxes: a comma-separated list or a repeat expression.
// Explicit type annotation: [Type; Size]
let explicit_array: [i32; 5] = [1, 2, 3, 4, 5];

// Type and size inferred by the compiler
let inferred_array = [1, 2, 3];

// Repeat expression: [initial_value; Size]
// The initial_value must implement `Copy`, be a constant item, or use an inline const block
let zeroed_array: [u8; 1024] = [0; 1024]; // Valid: 0 implements Copy

// Valid (Rust 1.79+): Using an inline const block to bypass the Copy requirement
let string_array: [String; 5] = [const { String::new() }; 5]; 
In a repeat expression, if the initial value does not implement the Copy trait, a direct function call (even a const fn) is evaluated as a standard expression and will result in a compiler error. Wrapping the initialization in an inline const block forces the compiler to evaluate it in a const context, allowing non-Copy types to be repeated.

Memory Layout

Arrays guarantee contiguous memory layout. The size of [T; N] in memory is exactly size_of::<T>() * N bytes, with no additional overhead or metadata stored alongside the array itself.

Element Access and Bounds Checking

Elements are accessed using zero-based indexing. Rust enforces strict bounds checking both at compile time and at runtime. Direct Indexing: Accessing an element via the index operator [] checks the index against the array’s length. If the index is statically known at compile time and exceeds the bounds, the compiler will emit an error (via the unconditional_panic lint), preventing compilation. If the index is dynamic, it is evaluated at runtime; an out-of-bounds access will cause the program to panic, preventing buffer over-read/write vulnerabilities.
let arr = [10, 20, 30];
let val = arr[1]; // Evaluates to 20

// let static_oob = arr[5]; // COMPILE-TIME ERROR: index out of bounds

let dynamic_index = 5;
// let runtime_oob = arr[dynamic_index]; // RUNTIME PANIC: index out of bounds
Safe Access: To handle out-of-bounds access gracefully without panicking, use the .get() method, which returns an Option<&T>.
let arr = [10, 20, 30];
let safe_val: Option<&i32> = arr.get(5); // Evaluates to None

Mutability

Like all variables in Rust, arrays are immutable by default. To modify elements, the array must be declared with the mut keyword. You can mutate individual elements, but you cannot change the array’s length.
let mut mutable_array = [1, 2, 3];
mutable_array[0] = 99; // Valid: modifies the first element

Iteration

Arrays implement the IntoIterator trait, allowing direct iteration over their elements. Modern Rust supports by-value iteration, which consumes the array and yields owned elements, as well as iteration by reference and mutable reference.
let arr = [10, 20, 30];

// By-value iteration (consumes the array, yields T)
for item in arr {
    // item is i32
}

// By-reference iteration (yields &T)
for item in &arr {
    // item is &i32
}

let mut mut_arr = [10, 20, 30];

// By-mutable-reference iteration (yields &mut T)
for item in &mut mut_arr {
    *item += 1;
}

Array Coercion to Slices

While arrays have a fixed size known at compile time, they frequently interact with dynamically-sized code via slices (&[T]). Rust automatically coerces a reference to an array (&[T; N]) into a slice (&[T]) when required by a function signature or method call.
let arr: [i32; 5] = [1, 2, 3, 4, 5];

// Creating a slice from a portion of the array
let slice: &[i32] = &arr[1..4]; // Contains [2, 3, 4]

// Implicit coercion from &[i32; 5] to &[i32]
let length = arr.len(); // .len() is a slice method
Master Rust with Deep Grasping Methodology!Learn More