2015-09-22 1 views
10

Ho un enum con molti valoriGet enum come stringa

enum Foo { 
    Bar = 0x00, 
    Baz = 0x01, 
    Qux = 0x02, 
    ... 
    Quux = 0xFF 
} 

e qualche volta mi piacerebbe scrivere il nome di uno dei suoi valori in un flusso. Posso ricavare Debug e fare

writer.write(format!("I am {:?}", Foo::Quux).as_bytes()) 

che sarà in uscita ad esempio I am Quux. Va bene, se non che

  • che voglio fare questo per l'uscita utente rivolto, in modo debug non è appropriato
  • Sarebbe molto utile per ottenere l'enumerazione come una stringa (piuttosto che scrivere direttamente a un flusso), perché quindi posso incorporare la sua lunghezza in alcuni calcoli di formattazione vistosi che voglio fare.

Qual è il modo migliore per raggiungere questo obiettivo?

risposta

17

Probabilmente il modo più semplice sarebbe quella di implementare Display chiamando in Debug:

impl fmt::Display for Foo { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "{:?}", self) 
     // or, alternatively: 
     // fmt::Debug::fmt(self, f) 
    } 
} 

quindi è possibile utilizzare to_string() per ottenere un String rappresentazione:

let s: String = Foo::Quux.to_string(); 

Se si dispone di molte enumerazioni cui si vuoi stampare, puoi scrivere una macro banale per generare l'implementazione sopra di Display per ognuno di essi.

Sfortunatamente, in Rust la programmazione riflessiva è alquanto difficile. Non esiste un modo standard, ad esempio, per ottenere un elenco di tutte le varianti di un enum di tipo C. Quasi sempre devi astrarre lo standard con macro personalizzate (o trovare qualcosa sulle casse.io). Forse questo cambierà in futuro se qualcuno scriverà un RFC e verrebbe accettato.

+4

Se si usa std :: fmt :: {self, Debug, Display} ', la semplice chiamata di' Debug :: fmt (self, f) 'è più semplice. – Veedrac

+0

Hai ragione, grazie! –