我有一个enum,看起来像这样:
#[repr(u8)]
pub enum PublicFlags {
PublicFlagVersion = 0x01,
PublicFlagReset = 0x02,
NoncePresent = 0x04,
IdPresent = 0x08,
PktNumLen4 = 0x30,
PktNumLen2 = 0x20,
PktNumLen1 = 0x10,
Multipath = 0x40,
}
字符串
我想对几个枚举值进行按位运算。然而,Rust编译器会抱怨:
an implementation of `std::ops::BitAnd` might be missing for `PublicFlags`.
型
4条答案
按热度按时间kyvafyod1#
Rust中的
enum
不打算用作位标志。PublicFlags
可以 * 仅 * 接受枚举中给定的值(而不是组合)。例如,下面的match语句是详尽的:字符串
没有办法让
PublicFlags
变量具有这些标志的组合。解决方案是将值实际存储为
u8
,然后使用常量存储每个标志的值。这可能很麻烦,但值得庆幸的是bitflags crate为您将所有样板文件打包在一个宏中。下面是一个如何使用位标志创建结构体的示例:型
knpiaxh12#
这可以作为没有新的依赖性的替代答案。
字符串
您可以像使用
PublicFlags::PublicFlagVersion
的枚举一样引用这些值,或者如果不指定命名空间而引用这些值更简洁,则添加use PublicFlags::*;
。t9aqgxwy3#
我不知道这在当时是否存在,但是一点
as
的魔力在没有任何bitor/bitand trait实现的情况下完成了这项工作(使代码有点长,但非常简单)字符串
PS:如果你不使用代码中的所有枚举,你会得到这个形状的警告:“warning:variant
TWO
is never constructed”,但是,同样,这只是一个可以优雅处理的警告。注意:当使用枚举进行按位操作时,项值不应重叠。在主要问题的代码中,至少
PktNumLen1
将与PublicFlagReset
和IdPresent
重叠,0x 10是0 b1010,0x 8是0 b1000,0x 2是0 b 0010(第2位和第4位重叠)72qzrwbm4#
我已经有了一个关于如何设置和使用枚举的答案,如果我们想要按位操作。
另一方面,我们可以将枚举值组合在一个向量(动态数组)中,并按原样使用它们:
字符串
这里的事情是在我们的函数中设置默认值(使用mut),并在稍后的代码中使用
match
来自定义它们。它易于编码,但这种方法的缺点是向量内每个标志的存储器使用。
在位操作方法中,ENUM值的位不应重叠。在这一方法中,预先思考过程至关重要。而且,解包比特字段也不容易,但是将它们存储在比特字段中使得存储器高效。所以也检查一下我的其他答案。(https://stackoverflow.com/a/76603396/9512475)