2017-04-20 7 views
6

私はこのようになります列挙持っている:私は、列挙値のいくつかのビットごとの操作を行いたいbitflags列挙型でビット単位の操作を実装する方法は?

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

を。しかし、錆コンパイラは文句:

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

答えて

9

ルストenumは、ビットフラグとして使用されるものではありません。 PublicFlags can は列挙型で与えられた値をとっています(組み合わせではありません)。たとえば、次の試合の文が網羅されるように:

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

フラグの組み合わせでPublicFlags変数を持ってする方法はありません。

解決策は実際には値をu8として実際に格納し、次に各フラグの値を格納する定数を使用することです。これは扱いにくいかもしれませんが、ありがたいことにbitflagsクレートはすべての定型文をマクロにラップします。ビットフラッグを使用して構造体を作成する方法の例を次に示します。

#[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

優秀!これは動作します!私はenumを 'u8'にキャストすることもできました。 –

関連する問題