I'm having trouble initializing a fixed length array. My attempts so far all result in the same "use of possibly uninitialized variable: foo_array
" error:
#[derive(Debug)] struct Foo { a: u32, b: u32 } impl Default for Foo { fn default() -> Foo { Foo{a:1, b:2} } } pub fn main() { let mut foo_array: [Foo; 10]; // Do something here to in-place initialize foo_array? for f in foo_array.iter() { println!("{:?}", f); } }
error[E0381]: use of possibly uninitialized variable: `foo_array` --> src/main.rs:13:14 | 13 | for f in foo_array.iter() { | ^^^^^^^^^ use of possibly uninitialized `foo_array`
I implemented the Default
trait, but Rust does not seem to call this by default akin to a C++ constructor.
What is the proper way to initialize a fixed length array? I'd like to do an efficient in-place initialization rather than some sort of copy.
Related: Why is the Copy trait needed for default (struct valued) array initialization?
Related: Is there a way to not have to initialize arrays twice?
The slow way to initialize your array with non-default values is to assign values one by one: int[] intArray = new int[10]; intArray[0] = 22; In this case, you declared an integer array object containing 10 elements, so you can initialize each element using its index value.
Use a tuple to declare an array with fixed length in TypeScript, e.g. const arr: [string, number] = ['a', 1] . Tuple types allow us to express an array with a fixed number of elements whose types are known, but can be different. Copied! We declared a tuple with 3 elements with types of string , number and number .
You initialize an array variable by including an array literal in a New clause and specifying the initial values of the array. You can either specify the type or allow it to be inferred from the values in the array literal.
The safe but somewhat inefficient solution:
#[derive(Copy, Clone, Debug)] struct Foo { a: u32, b: u32, } fn main() { let mut foo_array = [Foo { a: 10, b: 10 }; 10]; }
Since you're specifically asking for a solution without copies:
use std::mem::MaybeUninit; #[derive(Debug)] struct Foo { a: u32, b: u32, } // We're just implementing Drop to prove there are no unnecessary copies. impl Drop for Foo { fn drop(&mut self) { println!("Destructor running for a Foo"); } } pub fn main() { let array = { // Create an array of uninitialized values. let mut array: [MaybeUninit<Foo>; 10] = unsafe { MaybeUninit::uninit().assume_init() }; for (i, element) in array.iter_mut().enumerate() { let foo = Foo { a: i as u32, b: 0 }; *element = MaybeUninit::new(foo); } unsafe { std::mem::transmute::<_, [Foo; 10]>(array) } }; for element in array.iter() { println!("{:?}", element); } }
This is recommended by the documentation of MaybeUninit
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With