2014-10-03 3 views
9

Мне нужно инициализировать каждый элемент массива на непостоянное выражение. Могу ли я это сделать без необходимости сначала инициализировать каждый элемент массива каким-либо бессмысленным выражением? Вот пример того, что я хотел бы быть в состоянии сделать:Есть ли способ не инициализировать массивы дважды?

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, похоже, не имеет никакого значения.

ответ

11

Использование std::mem::uninitialized:

let mut ys: [i32; 1000] = unsafe { std::mem::uninitialized() }; 

Это небезопасно, поскольку доступ неинициализированным значения не определено поведение в Русте и компилятор больше не может гарантировать, что каждое значение ys будет инициализирован, прежде чем он будет читать.

вас cannot collect into an array, но если у вас 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 }