我想申请filter一个迭代器,我想出了这个并且它可以工作,但它超级详细:
.filter(|ref my_struct| match my_struct.my_enum { Unknown => false, _ => true })
Run Code Online (Sandbox Code Playgroud)
我宁愿写这样的东西:
.filter(|ref my_struct| my_struct.my_enum != Unknown)
Run Code Online (Sandbox Code Playgroud)
这给了我一个编译错误
binary operation `!=` cannot be applied to type `MyEnum`
Run Code Online (Sandbox Code Playgroud)
有冗长模式匹配的替代方案吗?我寻找一个宏但找不到合适的宏.
我找到了以下解决方案来创建一个宏,该宏定义一个函数,如果枚举与变体匹配,该函数将返回 true:
macro_rules! is_variant {
($name: ident, $enum_type: ty, $enum_pattern: pat) => {
fn $name(value: &$enum_type) -> bool {
matches!(value, $enum_pattern)
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
enum TestEnum {
A,
B(),
C(i32, i32),
}
is_variant!(is_a, TestEnum, TestEnum::A);
is_variant!(is_b, TestEnum, TestEnum::B());
is_variant!(is_c, TestEnum, TestEnum::C(_, _));
assert_eq!(is_a(&TestEnum::A), true);
assert_eq!(is_a(&TestEnum::B()), false);
assert_eq!(is_a(&TestEnum::C(1, 1)), false);
Run Code Online (Sandbox Code Playgroud)
有没有办法定义这个宏,以避免为变体数据提供占位符?
换句话说,更改宏以便能够像这样使用它:
is_variant!(is_a, TestEnum, TestEnum::A);
is_variant!(is_a, TestEnum, TestEnum::B);
is_variant!(is_a, TestEnum, TestEnum::C);
Run Code Online (Sandbox Code Playgroud)
使用(如仅按变体而不是值比较枚举std::mem::discriminant中所述)没有帮助,因为它只能用于比较两个枚举实例。在这种情况下,只有一个对象和变体标识符。它还提到了匹配,但如果变体没有数据,则不起作用。TestEnum::A(..)
学习 Rust 我碰巧需要比较嵌套枚举内的变体。考虑到以下枚举,我如何比较实例化的实际变体BuffTurget?
enum Attribute {
Strength,
Agility,
Intellect,
}
enum Parameter {
Health,
Mana,
}
enum BuffTarget {
Attribute(Attribute),
Parameter(Parameter),
}
Run Code Online (Sandbox Code Playgroud)
在网上搜索后,我找到了“判别式”,特别是像这样的比较函数:
fn variant_eq<T>(a: &T, b: &T) -> bool {
std::mem::discriminant(a) == std::mem::discriminant(b)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这个功能在我的情况下不起作用:
#[test]
fn variant_check_is_working() {
let str = BuffTarget::Attribute(Attribute::Strength);
let int = BuffTarget::Attribute(Attribute::Intellect);
assert_eq!(variant_eq(&str, &int), false);
}
// Output:
// thread 'tests::variant_check' panicked at 'assertion failed: `(left == right)`
// left: `true`,
// right: `false`', src/lib.rs:11:9
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望我的代码是这样的,使用if let:
let …Run Code Online (Sandbox Code Playgroud) 我有一个包含一些嵌套值的枚举.我想检查这个enum是给定的变体但是没有指定里面的内容.检查以下程序:
enum Test {
Zero,
One(u8),
Two(u16),
Four(u32),
}
fn check(x: Test, y: Test) -> bool {
x == y;
}
fn main() {
let x = Test::Two(10);
let b1 = check(x, Test::One);
let b2 = check(x, Test::Two);
let b3 = match x {
Test::Four(_) => true,
_ => false,
}
}
Run Code Online (Sandbox Code Playgroud)
b3检查内部x是否Test::Four具有任意值.我希望在函数中完成检查check.当前代码无法编译,我无法弄清楚如何在没有相应的内部值的情况下仅提取枚举变量.
我想这可以用宏转换到match表达式,但是没有宏可以做到吗?
我可以看到Test::One的fn(u16) -> Test {Two}.我能用这个事实吗?测试x是使用该函数创建的.
我想检查测试中具有字段的枚举,而现在暂时忽略字段的实际值。
考虑以下示例:
enum MyEnum {
WithoutFields,
WithFields { field: String },
}
fn return_with_fields() -> MyEnum {
MyEnum::WithFields {
field: "some string".into(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example() {
assert_eq!(return_with_fields(), MyEnum::WithFields {..});
}
}
Run Code Online (Sandbox Code Playgroud)
我想assert_eq!在这里使用,但是编译器告诉我:
enum MyEnum {
WithoutFields,
WithFields { field: String },
}
fn return_with_fields() -> MyEnum {
MyEnum::WithFields {
field: "some string".into(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example() {
assert_eq!(return_with_fields(), MyEnum::WithFields {..});
}
} …Run Code Online (Sandbox Code Playgroud) 我想将需要匹配的枚举的参数传递给参数,如下所示:
enum D {
A(i64),
B(u64),
C(u64, u64),
}
Run Code Online (Sandbox Code Playgroud)
let a = D.A(10);
println!(a.is_of(D.A)); // true
println!(a.is_of(D.B)); // false
Run Code Online (Sandbox Code Playgroud)
我知道我可以为此使用匹配规则,但是is_of出于我的目的,我希望此方法作为枚举选项的输入。
我有一个包含两个变体的枚举:
enum DatabaseType {
Memory,
RocksDB,
}
Run Code Online (Sandbox Code Playgroud)
如果在检查参数是否为DatabaseType::Memory或的函数内部进行条件化,我需要什么DatabaseType::RocksDB?
fn initialize(datastore: DatabaseType) -> Result<V, E> {
if /* Memory */ {
//..........
} else if /* RocksDB */ {
//..........
}
}
Run Code Online (Sandbox Code Playgroud)