Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicit partial array initialisation in Rust

Tags:

rust

In C, I can write int foo[100] = { 7, 8 }; and I will get [7, 8, 0, 0, 0...].

This allows me to explicitly and concisely choose initial values for a contiguous group of elements at the beginning of the array, and the remainder will be initialised as if they had static storage duration (i.e. to the zero value of the appropriate type).

Is there an equivalent in Rust?

like image 512
Iskar Jarak Avatar asked Sep 08 '15 08:09

Iskar Jarak


People also ask

How do you initialize an array in Rust?

If you need an array initialized with the same value repeated for each element, and the type of value contained in the array implements the Copy trait, Rust supports a shorthand syntax shown above. let _: [u8; 3] = [rng. gen(); 3]; One important thing to note from this example is that the copy happens after the rng.

Do Rust arrays implement copy?

Arrays of any size implement the following traits if the element type allows it: Copy. Clone. Debug.

Are Rust arrays mutable?

In Rust, an array is immutable, which means we cannot change its elements once it is created. However, we can create a mutable array by using the mut keyword before assigning it to a variable. For example, // create a mutable array in rust let mut numbers: [i32; 5] = [1, 2, 3, 4, 5];

How do you find the length of an array in Rust?

The length of an array is the number of elements present in the array. We use the len() function to obtain this value.


1 Answers

To the best of my knowledge, there is no such shortcut. You do have a few options, though.


The direct syntax

The direct syntax to initialize an array works with Copy types (integers are Copy):

let array = [0; 1024];

initializes an array of 1024 elements with all 0s.

Based on this, you can afterwards modify the array:

let array = {
    let mut array = [0; 1024];
    array[0] = 7;
    array[1] = 8;
    array
};

Note the trick of using a block expression to isolate the mutability to a smaller section of the code; we'll reuse it below.


The iterator syntax

There is also support to initialize an array from an iterator:

let array = {
    let mut array = [0; 1024];

    for (i, element) in array.iter_mut().enumerate().take(2) {
        *element = (i + 7);
    }

    array
};

And you can even (optionally) start from an uninitialized state, using an unsafe block:

let array = unsafe {
    // Create an uninitialized array.
    let mut array: [i32; 10] = mem::uninitialized();

    let nonzero = 2;

    for (i, element) in array.iter_mut().enumerate().take(nonzero) {
        // Overwrite `element` without running the destructor of the old value.
        ptr::write(element, i + 7)
    }

    for element in array.iter_mut().skip(nonzero) {
        // Overwrite `element` without running the destructor of the old value.
        ptr::write(element, 0)
    }

    array
};

The shorter iterator syntax

There is a shorter form, based on clone_from_slice, it is currently unstable however.

#![feature(clone_from_slice)]

let array = {
    let mut array = [0; 32];

    // Override beginning of array
    array.clone_from_slice(&[7, 8]);

    array
};
like image 157
Matthieu M. Avatar answered Sep 22 '22 08:09

Matthieu M.