2017-04-20 20 views
6

Mam enum, który wygląda tak:Jak zaimplementować operacje bitowe na wyliczeniu bitflagów?

#[repr(u8)] 
pub enum PublicFlags { 
    PublicFlagVersion = 0x01, 
    PublicFlagReset = 0x02, 
    NoncePresent = 0x04, 
    IdPresent = 0x08, 
    PktNumLen4 = 0x30, 
    PktNumLen2 = 0x20, 
    PktNumLen1 = 0x10, 
    Multipath = 0x40, 
} 

chcę zrobić na kilka operacji bitowej wartości enum. Jednak kompilator Rust narzeka:

an implementation of `std::ops::BitAnd` might be missing for `PublicFlags`. 

Odpowiedz

9

enum w Rust nie jest przeznaczony do stosowania jako flag bitowych. PublicFlags może tylko przyjąć wartości podane w wyliczeniu (a nie kombinacji). Tak na przykład, następujące oświadczenie mecz jest wyczerpująca:

let flags: PublicFlags; 
... 
match flags { 
    PublicFlagVersion => {...} 
    PublicFlagReset => {...} 
    NoncePresent => {...} 
    IdPresent => {...} 
    PktNumLen4 => {...} 
    PktNumLen2 => {...} 
    PktNumLen1 => {...} 
    Multipath => {...} 
} 

Nie ma sposobu, aby mieć PublicFlags zmienną kombinacją flag.

Rozwiązaniem jest faktyczne zapisanie wartości jako u8, a następnie użycie stałych do przechowywania wartości każdej flagi. Może to być uciążliwe, ale na szczęście skrzynia bitflags zawija dla Ciebie całą płytę podstawową w makrze. Oto przykład, jak utworzyć strukturę za pomocą bitflagów:

#[macro_use] 
extern crate bitflags; 

bitflags! { 
    flags PublicFlags: u8 { 
     const PUBLIC_FLAG_VERSION = 0x01, 
     const PUBLIC_FLAG_RESET = 0x02, 
     const NONCE_PRESENT = 0x04, 
     const ID_PRESENT = 0x08, 
     const PKT_NUM_LEN_4 = 0x30, 
     const PKT_NUM_LEN_2 = 0x20, 
     const PKT_NUM_LEN_1 = 0x10, 
     const MULTIPATH = 0x40, 
    } 
} 

fn main() { 
    let flag = PUBLIC_FLAG_VERSION | ID_PRESENT; 
    assert!((flag & MULTIPATH).is_empty()); 
    assert!(flag.contains(ID_PRESENT)); 
} 
+0

Świetnie! To działa! Byłem też w stanie rzucić enum na "u8". –