In some cases, you can use std::mem::MaybeUninit
:
use std::mem::MaybeUninit;
fn main() {
let mut ys: MaybeUninit<[i32; 1000]> = MaybeUninit::uninit();
}
Removing the MaybeUninit
wrapper via assume_init
is unsafe because accessing uninitialized values is undefined behavior in Rust and the compiler can no longer guarantee that every value of ys
will be initialized before it is read.
Your specific case is one of the examples in the MaybeUninit
docs; read it for a discussion about the safety of this implementation:
use std::mem::{self, MaybeUninit};
fn foo(xs: &[i32; 1000]) {
// I copied this code from Stack Overflow without
// reading why it is or is not safe.
let ys: [i32; 1000] = {
let mut ys: [MaybeUninit<i32>; 1000] = unsafe { MaybeUninit::uninit().assume_init() };
let mut xs = xs.into_iter();
for y in &mut ys[..] {
if let Some(x) = xs.next().copied() {
*y = MaybeUninit::new(x / 3);
}
}
unsafe { mem::transmute(ys) }
};
// ...
}
You cannot collect into an array, but if you had a Vec
instead, you could do:
let ys: Vec<_> = xs.iter().map(|&x| x / 3).collect();
For your specific problem, you could also clone the incoming array and then mutate it:
let mut ys = xs.clone();
for y in ys.iter_mut() { *y = *y / 3 }