2016-08-15 4 views
2

Hier ist, wo ich ab:Wie teilt man ein Enum in zwei Teile in verschiedenen Kisten auf?

#[derive(PartialEq)] 
enum ControlItem { 
    A { 
     name: &'static str, 
    }, 
    B { 
     name: &'static str, 
    }, 
} 

struct Control { 
    items: Vec<(ControlItem, bool)>, 
} 

impl Control { 
    pub fn set(&mut self, item: ControlItem, is_ok: bool) { 
     match self.items.iter().position(|ref x| (**x).0 == item) { 
      Some(idx) => { 
       self.items[idx].1 = is_ok; 
      } 
      None => { 
       self.items.push((item, is_ok)); 
      } 
     } 
    } 

    pub fn get(&self, item: ControlItem) -> bool { 
     match self.items.iter().position(|ref x| (**x).0 == item) { 
      Some(idx) => return self.items[idx].1, 
      None => return false, 
     } 
    } 
} 

fn main() { 
    let mut ctrl = Control { items: vec![] }; 
    ctrl.set(ControlItem::A { name: "a" }, true); 
    assert_eq!(ctrl.get(ControlItem::A { name: "a" }), true); 
    ctrl.set(ControlItem::B { name: "b" }, false); 
    assert_eq!(ctrl.get(ControlItem::B { name: "b" }), false); 
} 

Ich habe einen Control Typ, der den Zustand einiger vordefinierter Elemente speichern sollte und es zurück an Benutzer melden.

Ich habe einen virtuellen Tisch in meinem Kopf, wie folgt aus:

|Name in program | Name for user    | 
|item_1   | Item one bla-bla   | 
|item_2   | Item two bla-bla   | 
|item_3   | Item three another-bla-bla| 
  1. I Controlget/set Methoden haben wollen, die mit Namen item_1, item_2, item_3 nur Dinge zu akzeptieren.

  2. Ich möchte diesen virtuellen Tisch in zwei Kisten halten: "Main" und "Plattform". Die meisten der Implementierung von Control sollte in der Hauptkiste sein, und Definitionen der Elemente (wie item_3) sollten in die Plattform Kiste gehen. Ich möchte item_3 zur Kompilierzeit registrieren.

Irgendwelche Ideen, wie dies zu erreichen?

Antwort

0

Es klingt wie Sie sollten ein Merkmal, kein Enum verwenden. Sie könnten ein Merkmal definieren und es wie folgt implementieren:

pub trait ControlItem { 
    fn name(&self) -> &str; 
} 

struct A(&'static str); 

impl ControlItem for A { 
    fn name(&self) -> &str { 
     self.0 
    } 
} 

// ... similar struct and impl blocks for other items 

Dann können diese Strukturen in einzelne Kisten verschoben werden.

Sie müssen Control ändern, um ein Vec<(Box<ControlItem>, bool)> zu speichern und entweder ändern get und set ein Box<ControlItem> zu nehmen, oder generisch seine T: ControlItem über.

Lesen Sie über traits und trait objects für mehr.

+0

Das Problem mit 'ControlItem', das ich vordefinierte Menge von' ControlItem' haben möchte und kein anderes in 'set' und' get' erlauben möchte, ohne diese Einschränkung kann ich 'String' anstelle von' ControlItem' verwenden. – user1244932

+0

Aber Sie sagten, bevor Sie es öffnen wollten, so dass verschiedene 'ControlItem's in verschiedenen Kisten sein könnten. – durka42

+0

Ja, es sollte in verschiedenen Kisten sein, aber es sollte nur zur Kompilierzeit geöffnet werden. Eine Menge möglicher 'ControlItem' sollte zur Kompilierzeit festgelegt werden, und' set' und 'get' sollten nur sie akzeptieren. – user1244932

Verwandte Themen