Есть ли способ не инициализировать массивы дважды?
Мне нужно инициализировать каждый элемент массива неконстантным выражением. Могу ли я сделать это без предварительной инициализации каждого элемента массива каким-либо бессмысленным выражением? Вот пример того, что я хотел бы сделать:
fn foo(xs: &[i32; 1000]) {
let mut ys: [i32; 1000];
for (x, y) in xs.iter().zip(ys.iter_mut()) {
*y = *x / 3;
}
// ...
}
Этот код выдает ошибку во время компиляции:
error[E0381]: use of possibly uninitialized variable: `ys`
--> src/main.rs:5:37
|
5 | for (x, y) in xs.iter().zip(ys.iter_mut()) {
| ^^ use of possibly uninitialized `ys`
Чтобы решить проблему, мне нужно изменить первую строку функции, чтобы инициализировать элементы ys
с некоторыми фиктивными значениями, такими как:
let mut ys: [i32; 1000] = [0; 1000];
Есть ли способ пропустить эту дополнительную инициализацию? Заворачивая все в unsafe
блок, кажется, не имеет никакого значения.
2 ответа
Использование std::mem::uninitialized
:
let mut ys: [i32; 1000] = unsafe { std::mem::uninitialized() };
Это небезопасно, поскольку доступ к неинициализированным значениям является неопределенным поведением в Rust, и компилятор больше не может гарантировать, что каждое значение ys
будет инициализирован перед прочтением.
Вы не можете собрать в массив, но если у вас был Vec
вместо этого вы можете сделать:
let ys: Vec<_> = xs.iter().map(|&x| x / 3).collect();
Для вашей конкретной проблемы вы также можете клонировать входящий массив и затем изменить его:
let mut ys = xs.clone();
for y in ys.iter_mut() { *y = *y / 3 }
Вы можете использовать https://doc.rust-lang.org/stable/std/array/fn.from_fn.html
fn foo(xs: &[i32; 1000]) {
let ys: [i32; 1000] = array::from_fn(|i| (xs[i] / 3) as i32);