2015-02-22 32 views
11

Sto tentando di inizializzare un array di dimensioni fisse di un tipo annullabile, non copiabile, come un Option<Box<Thing>> per un tipo di Thing. Mi piacerebbe comprarne due in una struttura senza alcun riferimento indiretto. Mi piacerebbe scrivere qualcosa del genere:Inizializzazione di un array di dimensioni fisse di grandi dimensioni con tipi non di copia

let array: [Option<Box<Thing>>; SIZE] = [None; SIZE]; 

Ma non funziona perché la sintassi [e; n] richiede che e implementa Copy. Naturalmente, potrei estenderlo in SIZENone s, ma questo può essere poco pratico quando SIZE è grande. Non credo che questo possa essere fatto con una macro senza una codifica innaturale di SIZE. C'è un buon modo per farlo?

Sì, questo è facile con unsafe; c'è un modo per farlo senza unsafe?

+1

specificatamente per '[Opzione >; N] 'puoi usare transmute da a' [0; N] ': http://is.gd/CC31YQ –

+0

Ho scritto una risposta a una domanda simile http://stackoverflow.com/questions/36925673/how-can-i-initialize-an-array-using-a- funzione – malbarbo

risposta

2

sto copiando the answer by chris-morgan e adattandola per abbinare la domanda migliore, a seguire la raccomandazione dbaupp downthread, e per abbinare i recenti cambiamenti di sintassi:

use std::mem; 
use std::ptr; 

#[derive(Debug)] 
struct Thing { 
    number: usize, 
} 

macro_rules! make_array { 
    ($n:expr, $constructor:expr) => {{ 
     let mut items: [_; $n] = mem::uninitialized(); 
     for (i, place) in items.iter_mut().enumerate() { 
      ptr::write(place, $constructor(i)); 
     } 
     items 
    }} 
} 

const SIZE: usize = 50; 

fn main() { 
    let items = unsafe { make_array!(SIZE, |i| Box::new(Some(Thing { number: i }))) }; 
    println!("{:?}", &items[..]); 
} 

nota la necessità di utilizzare unsafe qui: Il problema è che se la funzione di costruzione panic! s, questo porterebbe a un comportamento non definito.

3

è possibile utilizzare il tratto Default per inizializzare l'array con i valori di default:

let array: [Option<Box<Thing>>; SIZE] = Default::default(); 

Vedi this playpen per un esempio di lavoro.

+2

Funziona con dimensioni fino a 32. – bluss

Problemi correlati