Constructing arrays

Constructing fixed length arrays, as opposed to "Vec", seems to be surprisingly difficult. Can't use .collect() on a map. Even initializing an array of Option<usize> to all None is hard, because Option is not copyable. So:

let mut result: [Option<MeshCoords>;3] = [None,None,None];

Fortunately there are only 3 entries. Updating such a structure has to be done imperatively:

for axis in 0..3 {
    if let Some(result_row) = &mut result[axis] {
          result_row.uv_data_array = new_uv_row(result_row, axis as u8);
    } 
}

I have to use actual assignment statements. Oh, the shame!

Is there a better way?

There is the array::map method which can be used for some cases:

[(); N].map(|()| None)
5 Likes

Option<T> is Copy if T is, and usize is certainly Copy. This works fine:

let xs: [Option<usize>; 3] = [None; 3];

For small array sizes, you can also use the Default implementation, which works with non-Copy types:

let xs: [Option<MeshCoords>; 3] = Default::default();

Unfortunately this breaks down for arrays of more than 32 elements, because there's already an unconditional impl<T> Default for [T; 0] and this would conflict with impl<T: Default, const N: usize> Default for [T; N], so core can't include the latter.

3 Likes

Besides Copy types, these expressions also support consts, e. g.

fn main() {
    const NONE: Option<String> = None;
    let x: [Option<String>; 10] = [NONE; 10];
}

playground

4 Likes

Yup, it is right now, for things that aren't Copy.

This will hopefully be better in Rust 1.62, because Stabilize `array_from_fn` by c410-f3r · Pull Request #94119 · rust-lang/rust · GitHub is hopefully going to stabilize from_fn in std::array - Rust in time for that release.

In the mean time, the easiest way it to use ArrayVec — data structures in Rust // Lib.rs, or the map trick that geeklint mentioned.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.