2014-10-03 10 views
9

Ich muss jedes Element eines Arrays zu einem nicht konstanten Ausdruck initialisieren. Kann ich das tun, ohne jedes Element des Arrays zuerst mit einem bedeutungslosen Ausdruck initialisieren zu müssen? Hier ist ein Beispiel dafür, was ich möchte in der Lage sein zu tun:Gibt es eine Möglichkeit, Arrays nicht zweimal initialisieren zu müssen?

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

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

Dieser Code gibt die Fehler bei der Kompilierung:

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` 

Um das Problem zu beheben muss ich die erste Zeile ändern die Funktion, die Elemente von ys mit einigen Dummy-Werte zu initialisieren, etwa so:

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

gibt es eine Möglichkeit, dass zusätzliche Initialisierung wegzulassen? Alles in einem unsafe Block zu verpacken scheint keinen Unterschied zu machen.

Antwort

11

Verwendung std::mem::uninitialized:

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

Dies ist unsicher, da nicht initialisierte Werte Zugriff in Rust undefiniertes Verhalten ist und der Compiler kann nicht mehr garantieren, dass jeder Wert von ys initialisiert werden, bevor es gelesen wird.

Sie cannot collect into an array, aber wenn man stattdessen eine Vec hätten, könnten Sie tun:

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

Für Ihr spezielles Problem, können Sie auch das eingehende Array klonen und dann mutieren:

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