2015-09-08 2 views
9

In C, posso scrivere int foo[100] = { 7, 8 }; e riceverò [7, 8, 0, 0, 0...].Inizializzazione di array parziale esplicita in Rust

Questo mi consente di scegliere in modo esplicito e conciso i valori iniziali per un gruppo contiguo di elementi all'inizio della matrice e il resto verrà inizializzato come se avessero una durata di archiviazione statica (cioè al valore zero del tipo appropriato).

Esiste un equivalente in Rust?

risposta

12

In base alle mie conoscenze, non esiste una tale scorciatoia. Hai alcune opzioni, però.


La sintassi diretta

La sintassi diretta per inizializzare un array funziona con Copy tipo (interi sono Copy):

let array = [0; 1024]; 

inizializza un array di 1024 elementi con tutti 0.

Sulla base di questo, è possibile poi modificare la matrice:

let array = { 
    let mut array = [0; 1024]; 
    array[0] = 7; 
    array[1] = 8; 
    array 
}; 

nota il trucco di usare un espressione di blocco per isolare la mutevolezza ad una sezione più piccola del codice; lo riutilizzeremo di seguito.


La sintassi iteratore

C'è anche il supporto per inizializzare un array da un iteratore:

let array = { 
    let mut array = [0; 1024]; 

    for (i, element) in array.iter_mut().enumerate().take(2) { 
     *element = (i + 7); 
    } 

    array 
}; 

e si può anche (opzionalmente) iniziare da uno stato non inizializzato, utilizzando un blocco unsafe:

let array = unsafe { 
    // Create an uninitialized array. 
    let mut array: [i32; 10] = mem::uninitialized(); 

    let nonzero = 2; 

    for (i, element) in array.iter_mut().enumerate().take(nonzero) { 
     // Overwrite `element` without running the destructor of the old value. 
     ptr::write(element, i + 7) 
    } 

    for element in array.iter_mut().skip(nonzero) { 
     // Overwrite `element` without running the destructor of the old value. 
     ptr::write(element, 0) 
    } 

    array 
}; 

L'iteratore sintassi più breve

C'è una forma più breve, sulla base di clone_from_slice, è attualmente instabile comunque.

#![feature(clone_from_slice)] 

let array = { 
    let mut array = [0; 32]; 

    // Override beginning of array 
    array.clone_from_slice(&[7, 8]); 

    array 
}; 
2

Ecco macro

macro_rules! array { 
    ($($v:expr),*) => (
     { 
      let mut array = Default::default(); 
      { 
       let mut e = <_ as ::std::convert::AsMut<[_]>>::as_mut(&mut array).iter_mut(); 
       $(*e.next().unwrap() = $v);*; 
      } 
      array 
     } 
    ) 
} 

fn main() { 
    let a: [usize; 5] = array!(7, 8); 
    assert_eq!([7, 8, 0, 0, 0], a); 
}