2016-12-21 5 views
2

D-Bus를 통해 NetworkManager과 상호 작용하는 코드를 작성하고 있는데 키 - 값 방식처럼 enum을 사용하고 싶습니다. 그렇게하는 가장 깨끗한, 가장 관용적 인 방법은 무엇양방향 조회 테이블로 Rust의 열거 형을 사용하십시오.

pub enum NetworkManagerState { 
    Unknown = 0, 
    Asleep = 10, 
    Disconnected = 20, 
    Disconnecting = 30, 
    Connecting = 40, 
    ConnectedLocal = 50, 
    ConnectedSite = 60, 
    ConnectedGlobal = 70, 
} 

:

예를 들어,이 enum의 문자열 Unknown를 사용하는 숫자 0으로 다른 맥락에서 값 0를 사용하여 한 번에 원하는 ? 튜플 기반의 열거 형을 정의하여 각 항목이 (ConnectedSite, 60u32, "Connected")처럼 보이고 컨텍스트에 따라 각 튜플 속성을 사용하는 방법이 있습니까?

+1

매크로가 필요합니다. – Shepmaster

+0

저는 녹 사용자가 아니지만 관용적 인 녹이 문자열 값을 피하는 것을 선호합니다 (성능상의 이유로). 처음 만났을 때 문자열 값을 구문 분석 한 다음 모든 후속 처리에 해당 열거 형 값을 사용할 수있는 방법이 있습니까? – Dai

답변

5
  1. enum을 int로 변환하려면 as i32을 사용할 수 있습니다. 특성에서를 사용하여

    #[macro_use] 
    extern crate enum_primitive; 
    use enum_primitive::FromPrimitive; 
    
    enum_from_primitive! { 
    #[derive(Debug, PartialEq)] 
    pub enum NetworkManagerState { 
        Unknown = 0, 
        Asleep = 10, 
        Disconnected = 20, 
        Disconnecting = 30, 
        Connecting = 40, 
        ConnectedLocal = 50, 
        ConnectedSite = 60, 
        ConnectedGlobal = 70, 
    } 
    } 
    
    impl From<i32> for NetworkManagerState { 
        fn from(val: i32) -> NetworkManagerState { 
         NetworkManagerState::from_i32(val).expect("passed Value does not match an enum value!") 
        } 
    } 
    impl From<NetworkManagerState> for i32 { 
        fn from(val: NetworkManagerState) -> i32 { 
         val as i32 
        } 
    } 
    
    
    fn main() { 
        let value_i32 = 40; 
        let value_enum = NetworkManagerState::Connecting; 
    
        // enum to i32 
        println!("{:?}", value_enum as i32); 
    
        // i32 to enum 
        println!("{:?}", NetworkManagerState::from_i32(value_i32).unwrap()); 
    
        // using from trait 
        let y: i32 = NetworkManagerState::Connecting.into(); 
        println!("{:?}", y); 
    
        // using from trait 
        let x: NetworkManagerState = 40.into(); 
        println!("{:?}", x); 
    } 
    

    :

cargo.toml :

[dependencies] 
enum_primitive = "*" 

main.rs

  • 당신이 enum_primitive 상자를 사용할 수 있습니다 귀하의 열거에 I32 캐스팅 열거 형으로 변환 할 수있는 모든 것을 수락하도록 함수를 만들 수 있습니다.

    fn fancy_function<T: Into<NetworkManagerState>>(value: T) { 
        let internal: NetworkManagerState = value.into(); 
        println!("{:?}", internal); 
    } 
    
    ... 
    
    fancy_function(60); 
    fancy_function(NetworkManagerState::Asleep);