Start learning free

LESSON 97 OF 414 · ARRAYS I

Static Arrays in Rust: Fixed-Size [T; N] Arrays

Lesson Read the full explanation

When we're dealing with large amounts of data, we want to make sure we can organize and manage it properly.

In Rust, we use arrays to store several pieces of data in one place. The items in an array must be of the same data type.

A static array or fixed array is an array for which the size / length is determined when the array is created and/or allocated.


Creation:

We create a static array by writing the array's name followed by its type, [T; N], where T is the element type and N is the length, like this:

let array_of_strings: [&str; 5] = [""; 5];

This code creates an array named array_of_strings that consists of 5 &str items.

These 5 items are initialized with empty strings "" automatically.


Creation & Initialization:

There is a way to initialize an array at creation by using the = operator with an opening bracket, end it with a closing bracket, and put a comma between each entry, like this:

let array_of_strings = ["AlgoCademy", "coding", "static arrays"];

We created an array named array_of_strings which consists of 3 string items: "AlgoCademy", "coding" and "static arrays".


Assignment
Follow the Coding Tutorial and let's play with some arrays.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 2
    Ctrl + Enter to check

    RUST · ARRAYS I

    Static Arrays in Rust, explained

    What a static array is

    An array holds several values of the same type in one place, one after another in memory. In Rust, the usual array is a static (or fixed-size) array: its length is part of its type and is known when the program is compiled. Once created, it never grows or shrinks. You write its type as [T; N], where T is the element type and N is the number of elements. An array of five integers has type [i32; 5], and an array of three string slices has type [&str; 3].

    Because the size is fixed, use an array when the count never changes, such as the days of a week or the coordinates of a point. When you need to add or remove elements, use a Vec, which the next lessons cover.

    Creating arrays

    There are two common forms. The first repeats one value N times:

    let array_of_strings: [&str; 5] = [""; 5];
    let numbers = [0; 20];
    

    The first line has an explicit type and fills five slots with the empty string. The second lets Rust infer the type: numbers is a [i32; 20], twenty zeros, because integer literals default to i32. The part before the semicolon is the value and the part after it is the length, which must be a constant known at compile time.

    The second form lists the elements, separated by commas:

    let fruits = ["mango", "kiwi", "grapefruit"];
    

    Here the length is the number of items, so fruits is a [&str; 3]. String literals have the type &str.

    Useful things to know

    • The length is part of the type. A [i32; 3] and a [i32; 4] are different types. Writing let a: [i32; 3] = [1, 2]; fails to compile with an error saying it expected an array with a size of 3 and found one with a size of 2.
    • Every element has the same type. You can't mix numbers and strings in one array.
    • Arrays can be nested. [[0; 3]; 2] is two rows of three zeros. Printed with {:?}, it shows [[0, 0, 0], [0, 0, 0]].
    • len() gives the length. numbers.len() is 20. It returns a usize.
    • Arrays of copyable elements are copied on assignment. After let mut b = a; with a an array of integers, changing b[0] leaves a untouched, because b is a separate copy.
    • Printing needs {:?}. The plain {} placeholder doesn't work for arrays, because they have no default text form. println!("{:?}", fruits) prints ["mango", "kiwi", "grapefruit"].

    Comparing and checking arrays

    Two arrays of the same length and element type can be compared with ==. The comparison is element by element, so fruits == ["mango", "kiwi", "grapefruit"] is true.

    To test a property of every element, use an iterator. numbers.iter() goes through the elements by reference, and all returns true only if its closure returns true for every one of them:

    numbers.iter().all(|&x| x == 0)
    

    The pattern |&x| in the closure takes each integer out of its reference, so x is a plain i32 that can be compared to 0.

    The lesson's exercise

    The exercise creates two arrays and then verifies them.

    1. Create numbers as twenty zeros with [0; 20], and fruits as the three names in a list.
    2. Print a check for numbers. In Rust, if is an expression, so if numbers.iter().all(|&x| x == 0) { 1 } else { 0 } produces the value to print, 1 when all twenty are zero and 0 otherwise.
    3. Print a check for fruits. The same shape, with fruits == ["mango", "kiwi", "grapefruit"] as the condition.
    let numbers = [0; 20];
    let fruits = ["mango", "kiwi", "grapefruit"];
    
    println!("{}", if numbers.iter().all(|&x| x == 0) { 1 } else { 0 });
    println!("{}", if fruits == ["mango", "kiwi", "grapefruit"] { 1 } else { 0 });
    

    Both lines print 1. The two branches of the if must have the same type; here both are integers, and the {} placeholder prints the chosen one.

    Common mistakes

    • Treating an array as growable. There is no push on an array. If the size changes at run time, switch to a Vec.
    • A non-constant length. [0; n] with n being a variable that is computed at run time is an error, since the length must be known at compile time. Use vec![0; n] for that.
    • Confusing the semicolon with a comma. [0; 20] is twenty zeros. [0, 20] is an array of two elements, 0 and 20.
    • Wrong-length literals. The number of items in a list must match N in the annotated type.
    • Mismatched comparisons. Arrays of different lengths can't be compared with == in this way, because they are different types.

    Key takeaways

    • An array has the type [T; N], with a fixed length and one element type.
    • [value; N] repeats a value, and [a, b, c] lists the elements.
    • Use == to compare whole arrays, iter().all(...) to test every element and {:?} to print.
    • When the size must change, use a Vec.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free