2016-04-29 8 views
6

posso fare questo:enumerazioni con valori costanti a Rust

enum MyEnum { 
    A(i32), 
    B(i32), 
} 

ma non questa:

enum MyEnum { 
    A(123), // 123 is a constant 
    B(456), // 456 is a constant 
} 

posso creare le strutture per A e B con un singolo campo e quindi implementare quel campo , ma penso che potrebbe esserci un modo più semplice. C'è qualche?

risposta

20

Il modo migliore per rispondere a questa sta lavorando perché si vuole costanti in un enum: sei solo associando un valore con ogni variante, o non si desidera che ogni variante alla essere tale valore (come un enum in C o C++)?

Per il primo caso, probabilmente ha più senso di lasciare solo le varianti enum senza dati, e fare una funzione:

enum MyEnum { 
    A, 
    B, 
} 

impl MyEnum { 
    fn value(&self) -> i32 { 
     match *self { 
      MyEnum::A => 123, 
      MyEnum::B => 456, 
     } 
    } 
} 
// call like some_myenum_value.value() 

Questo approccio può essere applicato più volte, ad associare molti pezzi separati di informazioni con ogni variante, ad es forse vuoi anche un metodo .name() -> &'static str.

In alternativa, per il secondo caso, è possibile assegnare i valori delle variabili esplicite proprio come C/C++:

enum MyEnum { 
    A = 123, 
    B = 456, 
} 

questo può essere match ed in in tutti allo stesso modo, ma può anche essere lanciato in un intero MyEnum::A as i32. (Si noti che i calcoli come MyEnum::A | MyEnum::B non sono automaticamente legale in Rust: enumerazioni hanno valori specifici, non sono bit-flag.)

1

Persone in cerca di questo può inciampare su l'introduzione e la disapprovazione di FromPrimitive. Una possibile sostituzione che potrebbe essere utile anche qui è enum_primitive. Ti permette di usare enumerazioni simili a C e di farle rappresentare tra rappresentazione numerica e logica:

#[macro_use] 
extern crate enum_primitive; 
extern crate num; 

use num::FromPrimitive; 

enum_from_primitive! { 
    #[derive(Debug, PartialEq)] 
    enum FooBar { 
     Foo = 17, 
     Bar = 42, 
     Baz, 
    } 
} 

fn main() { 
    assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo)); 
    assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar)); 
    assert_eq!(FooBar::from_i32(43), Some(FooBar::Baz)); 
    assert_eq!(FooBar::from_i32(91), None); 
} 
Problemi correlati