2015-11-09 9 views
5

Questo codice viene compilato correttamente. Ha alcuni avvisi di codice inutilizzati, ma per ora va bene.Quando e come utilizzare un vettore di riferimenti

use std::collections::BTreeMap; 

enum Object<'a> { 
    Str(String), 
    Int(i32), 
    Float(f32), 
    Vector(Vec<&'a Object<'a>>), 
    Prim(fn(State) -> State) 
} 

struct State<'a> { 
    named: BTreeMap<String, &'a Object<'a>>, 
    stack: Vec<Object<'a>> 

} 

impl<'a> State<'a> { 
    fn push_int(&mut self, x: i32) { 
     self.stack.push(Object::Int(x)); 
    } 
} 


fn main() { 
    println!("Hello, world!"); 
    let obj = Object::Str("this is a test".to_string()); 
} 

La parte importante di questo codice è push_int e stack: Vec<Object<'a>>.

Sto cercando di creare una macchina virtuale basata su stack. Voglio passare lo stato alle funzioni, che possono togliere elementi dallo stack, manipolare il materiale e quindi rimettere alcuni elementi in pila; il campo con nome sta per contenere oggetti con nome.

Ho la sensazione che sarebbe preferibile avere lo stack rappresentato come Vec<&'a Object<'a>>. Nel modo in cui l'ho adesso, temo di commettere un errore di inefficienza. La mia impressione è corretta?

La seconda parte del problema è che non so come far funzionare il vettore della versione dei riferimenti. Creare un nuovo valore con le giuste vite per spingere in pila non funziona per me.

Sono un po 'vago in merito a questo problema, quindi se non sono chiaro, chiedimi domande per chiarire le cose.

+0

Si desidera 'Vec >>' per un puntatore di proprietà.Si ha inefficienza, in quanto 'Object :: Int' occupa tanto spazio come' Object :: String', ma la boxing lo renderà peggio (anche se il boxing ha permesso rappresentazioni più compatte). Vorrei semplicemente cambiare 'Str (String)' a 'Str (Box )' e 'Vector >' a 'Vector >>' e lasciarlo a quello, dato che rimuove solo le cose mantenendo anche 'Object' * * grande. È ancora possibile che l'indiretta in più sia peggio dell'inefficienza per valori più piccoli (probabilmente più comuni). – Veedrac

+1

cosa intendi con "inefficienza"? Stai chiedendo come risparmiare memoria o come essere più performante? Inoltre penso che questa domanda sia su http://codereview.stackexchange.com/ –

+0

@ker Penso che intendessi entrambi; Ero vago perché non ne sapevo abbastanza per essere più specifico. Sì, potrebbe essere andato a codeview; Non ero sicuro – phil

risposta

6

Il motivo per cui non è stato possibile farlo funzionare è che le strutture non possono avere campi che si riferiscono ad altri campi. (Vedere sostenere link in fondo.)

Cosa si può fare, è mettere tutti i Object s nella vostra Vec, e hanno il HashMap contengono gli indici degli elementi di nome fa riferimento.

struct State { 
    named: BTreeMap<String, usize>, 
    stack: Vec<Object> 
} 

Mi piacerebbe anche rimuovere tutte le vite dal vostro esempio, come questo può essere fatto completamente con gli oggetti di proprietà.

enum Object { 
    Str(String), 
    Int(i32), 
    Float(f32), 
    Vector(Vec<Object>), 
    Prim(fn(State) -> State) 
} 

È possibile provare un'implementazione lavoro nei Playground

link di supporto:

+2

Un punto di stile riguardante "(sì, ogni parola è un collegamento diverso)". Un elenco puntato di link ad altre domande di Overflow dello stack è più chiaro da sfogliare, perché SO cercherà automaticamente i titoli e li mostrerà. –