如何在位标志枚举上实现按位运算? [英] How to implement bitwise operations on a bitflags enum?

查看:63
本文介绍了如何在位标志枚举上实现按位运算?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像这样的枚举:

I have an enum that looks like this:

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

我想对几个枚举值进行按位运算.然而,Rust 编译器抱怨:

I want to do a bitwise operation on several of the enum values. However, the Rust compiler complains:

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

推荐答案

Rust 中的 enum 不打算用作位标志.PublicFlags 可以采用枚举中给出的值(而不是组合).例如,以下 match 语句是详尽无遗的:

An enum in Rust is not intended to be used as bit flags. PublicFlags can only take the values given in the enum (and not a combination). So for instance, the following match statement is exhaustive:

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

没有办法将 PublicFlags 变量与标志组合在一起.

There is no way to have a PublicFlags variable with a combination of the flags.

解决方案是将值实际存储为u8,然后使用常量来存储每个标志的值.这可能很麻烦,但幸运的是 bitflags 板条箱将所有样板包装在一个宏中为你.以下是如何使用位标​​志创建结构的示例:

The solution is to actually store the value as a u8, then use constants to store the value of each flag. This can be cumbersome, but thankfully the bitflags crate wraps all the boilerplate up in a macro for you. Here is an example how you would create your struct using 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));
} 

这篇关于如何在位标志枚举上实现按位运算?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆