Because I am dealing with an environment with certain memory constraints, I need to allocate a very large statically sized array at the beginning of my program's execution:
let mut data: [Foo; 1024] = ?
How can I initialize this array with "empty" data?
I have tried using the default
method, since Foo
also has a default:
let mut data: [Foo; 1024] = Default::default(),
but it doesn't work, because array
only implements default for a fixed set of sizes:
error[E0277]: the trait bound `[foo::Foo; 1024]: std::default::Default` is not satisfied
--> /src/foo.rs:143:22
|
143 | = Default::default(),
| ^^^^^^^^^^^^^^^^ the trait `std::default::Default` is not implemented for `[foo::Foo; 1024]`
|
= help: the following other types implement trait `std::default::Default`:
&[T]
&mut [T]
[T; 0]
[T; 10]
[T; 11]
[T; 12]
[T; 13]
[T; 14]
and 27 others
How can I initialize such a large statically sized array without typing a giant literal in my code?
CodePudding user response:
To repeat some data in an array several times we use [{data}; {times}]
. So you need this:
let mut data = [Foo::default(); 1024];
Annotation here is unnecessary because we specified type and length in variable’s value.
CodePudding user response:
Thanks to the documentation of MaybeUninit
, we can provide our own way to initialise this array.
Obviously, this is only useful if you don't want Foo
to implement Copy
, otherwise the trivial usual notation ([value; repeat]
) applies (but the question probably wouldn't have been asked ;^)
use std::mem::MaybeUninit;
struct Foo {
a: u8,
b: u8,
}
fn main() {
let data: [Foo; 1024] = {
let mut data: [MaybeUninit<Foo>; 1024] =
unsafe { MaybeUninit::uninit().assume_init() };
for f in data.iter_mut() {
f.write(Foo { a: u8::MAX, b: 0 });
}
unsafe { std::mem::transmute(data) }
};
for f in data.iter() {
assert_eq!(f.a, u8::MAX);
assert_eq!(f.b, 0);
}
}