2015-11-09 14 views
5

Ten kod poprawnie się kompiluje. Ma kilka nieużywanych ostrzeżeń kodu, ale na razie jest to w porządku.Kiedy i jak korzystać z wektora odnośników

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()); 
} 

Ważną częścią tego kodu jest push_int i stack: Vec<Object<'a>>.

Próbuję zrobić maszynę wirtualną opartą na stosie. Chcę przekazać stan do funkcji, które mogą usuwać rzeczy ze stosu, manipulować nimi, a następnie umieszczać pewne rzeczy na stosie; nazwane pole będzie zawierało nazwane obiekty.

Mam przeczucie, że lepiej będzie, gdy stos będzie reprezentowany jako Vec<&'a Object<'a>>. Sposób, w jaki mam to teraz, obawiam się, że popełniam błąd nieefektywności. Czy moje przeczucie jest prawidłowe?

Druga część problemu polega na tym, że nie wiem, jak uruchomić wektor wersji referencyjnej. Tworzenie nowej wartości z odpowiednimi wcieleniami, które można przenieść na stos, nie działa dla mnie.

Jestem trochę niejasny w tej kwestii, więc jeśli byłem niejasny, zadaj mi pytania, aby wyjaśnić pewne kwestie.

+0

Użytkownik chciał by 'Vec >>' dla posiadanego wskaźnika.Masz nieefektywność, ponieważ 'Object :: Int' zajmuje tyle miejsca co' Object :: String', ale boksowanie go po prostu pogorszy (nawet jeśli boks pozwolił na bardziej zwarte reprezentacje). Chciałbym zmienić 'Str (String)' na 'Str (Box )' i 'Vector >' na 'Vector >>' i pozostaw to w tym miejscu, ponieważ to usuwa jedyne rzeczy utrzymujące 'Object' * również * duży. Nadal jest możliwe, że dodatkowy kierunek jest gorszy niż nieefektywność w przypadku mniejszych (prawdopodobnie bardziej powszechnych) wartości. – Veedrac

+1

co masz na myśli mówiąc "nieefektywność"? Czy pytasz, jak oszczędzać pamięć lub jak być bardziej wydajnym? Też myślę, że to pytanie należy do http://codereview.stackexchange.com/ –

+0

@ker Myślę, że miałem na myśli obie; Byłem niejasny, ponieważ nie wiedziałem wystarczająco dużo, aby być bardziej szczegółowym. Tak, mógł przejść do przeglądu kodu; Nie byłem pewien. – phil

Odpowiedz

6

Powodem, dla którego nie można go uruchomić, jest to, że pliki struct nie mogą zawierać pól odnoszących się do innych pól. (Patrz wspieranie linki na dole).

Co można zrobić, to umieścić wszystkie Object s do swojej Vec, i mieć HashMap zawierają wskaźników wymienionych elementów to referencje.

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

Usunąłbym również wszystkie życiowe egzemplarze ze swojego przykładu, ponieważ można to zrobić całkowicie z posiadanymi przedmiotami.

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

Można wypróbować realizację pracujących w Playground

Wspieranie powiązań:

+2

Punkt stylistyczny dotyczący "(tak, każde słowo to inny link)". Wypunktowana lista linków do innych pytań związanych z przepełnieniem stosu jest bardziej przejrzysta do przeglądania, ponieważ SO automatycznie wyszukuje tytuły i pokazuje je. –