2014-10-03 9 views
9

Devo inizializzare ogni elemento di una matrice su un'espressione non costante. Posso farlo senza dover prima inizializzare ogni elemento dell'array con un'espressione priva di significato? Ecco un esempio di quello che mi piacerebbe essere in grado di fare:C'è un modo per non dover inizializzare gli array due volte?

fn foo(xs: &[i32; 1000]) { 
    let mut ys: [i32; 1000]; 

    for (x, y) in xs.iter().zip(ys.iter_mut()) { 
     *y = *x/3; 
    } 
    // ... 
} 

Questo codice dà l'errore in fase di compilazione:

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` 

Per risolvere il problema ho bisogno di cambiare la prima linea di la funzione per inizializzare gli elementi di ys con alcuni valori fittizi in questo modo:

let mut ys: [i32; 1000] = [0; 1000]; 

esiste un modo per omettere che l'inizializzazione in più? Disporre tutto in un blocco unsafe non sembra fare alcuna differenza.

risposta

11

Uso std::mem::uninitialized:

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

Questo è pericoloso perché l'accesso valori non inizializzati è un comportamento indefinito di Rust e il compilatore non può più garantire che ogni valore ys verrà inizializzato prima di essere letta.

È cannot collect into an array, ma se si ha un Vec, invece, si potrebbe fare:

let ys: Vec<_> = xs.iter().map(|&x| x/3).collect(); 

Per il vostro problema specifico, si potrebbe anche clonare la matrice in entrata e poi mutare è:

let mut ys = xs.clone(); 
for y in ys.iter_mut() { *y = *y/3 }