Rust 在宏中匹配多个枚举类型

Rust 在宏中匹配多个枚举类型,rust,macros,Rust,Macros,我有一个宏,用于将框与不同的枚举匹配。对于我现在使用的版本,我需要在if-else链中为我想要匹配的每个错误类型重复调用它 #[macro_export] macro_rules! dyn_match { ($e:expr, $($pat:pat => $result:expr),*) => ( if let Some(e) = $e.downcast_ref() { match e { $(

我有一个宏,用于将
与不同的枚举匹配。对于我现在使用的版本,我需要在if-else链中为我想要匹配的每个错误类型重复调用它

#[macro_export]
macro_rules! dyn_match {
    ($e:expr, $($pat:pat => $result:expr),*) => (
        if let Some(e) = $e.downcast_ref() {
            match e {
                $(
                    $pat => {$result; true}
                ),*
            }
        } else {false}
    );
}

...
//fn example(x: u32) -> Result<u32, Box<dyn error::Error>>;
match example(9) {
    Ok(_) => Ok(()),
    Err(e) => {
        if dyn_match!(e, 
            ExampleError1::ThisError(2) => panic!("it was 2!"),
            i => {}
        ) {Ok(())}
        else if dyn_match!(e,
            ExampleError2::ThatError(8) => panic!("it was 8!"),
            ExampleError2::ThatError(9) => panic!("it was 9!"),
            i => {}
        ) {Ok(())}
        else {panic!("{}",e)}
    }
}
...
我不熟悉宏,但在编译过程中进行扩展时,它应该能够看到每个匹配项将与哪个类型进行比较,并隐式地向下转换到该类型。我真的不知道如何解决这个问题。有什么想法吗?

明白了

#[macro_export]
macro_rules! dynmatch {
    ($e:expr, $(type $ty:ty {$(arm $pat:pat => $result:expr),*, _ => $any:expr}),*, _ => $end:expr) => (
        $(
            if let Some(e) = $e.downcast_ref::<$ty>() {
                match e {
                    $(
                        $pat => {$result}
                    )*
                    _ => $any
                }
            } else
        )*
        {$end}
    );
}
...
        let _i = match example(3) {
            Ok(i) => i,
            Err(e) => {
                dynmatch!(e,                                                    //the dynamic error to be matched
                    type ExampleError1 {                                        //an error group
                        arm ExampleError1::ThisError(2) => panic!("it was 2!"), //arm [pattern] => {code}
                        _ => panic!("{}",e)                                     //_ => {code}
                    },
                    type ExampleError2 {
                        arm ExampleError2::ThatError(8) => panic!("it was 8!"),
                        arm ExampleError2::ThatError(9) => 9,
                        _ => panic!("{}",e)
                    }, 
                    _ => panic!("{}",e)                                         //what to do if error group isn't found
                )
            }
        };
...
#[宏导出]
宏规则!dynmatch{
($e:expr,$(键入$ty:ty{$(arm$pat:pat=>$result:expr),*,=>$any:expr}),*,=>$end:expr)=>(
$(
如果让一些(e)=$e.downcast_ref:(){
匹配e{
$(
$pat=>{$result}
)*
_=>$any
}
}否则
)*
{$end}
);
}
...
让_i=匹配示例(3){
好的(i)=>i,
错误(e)=>{
dynmatch!(e,//要匹配的动态错误
键入ExampleError1{//错误组
arm ExampleError1::ThisError(2)=>panic!(“它是2!”),//arm[pattern]=>{code}
_=>惊慌失措!(“{}”,e)/{{code}
},
输入示例Error2{
arm ExampleError2::ThatError(8)=>恐慌!(“是8!”),
arm示例错误2::该错误(9)=>9,
_=>恐慌!(“{}”,e)
}, 
_=>panic!(“{}”,e)//如果找不到错误组,该怎么办
)
}
};
...
解决方案的成功归功于。 此外,如果有人对更好的解决方案有任何想法,请让我知道

#[macro_export]
macro_rules! dynmatch {
    ($e:expr, $(type $ty:ty {$(arm $pat:pat => $result:expr),*, _ => $any:expr}),*, _ => $end:expr) => (
        $(
            if let Some(e) = $e.downcast_ref::<$ty>() {
                match e {
                    $(
                        $pat => {$result}
                    )*
                    _ => $any
                }
            } else
        )*
        {$end}
    );
}
...
        let _i = match example(3) {
            Ok(i) => i,
            Err(e) => {
                dynmatch!(e,                                                    //the dynamic error to be matched
                    type ExampleError1 {                                        //an error group
                        arm ExampleError1::ThisError(2) => panic!("it was 2!"), //arm [pattern] => {code}
                        _ => panic!("{}",e)                                     //_ => {code}
                    },
                    type ExampleError2 {
                        arm ExampleError2::ThatError(8) => panic!("it was 8!"),
                        arm ExampleError2::ThatError(9) => 9,
                        _ => panic!("{}",e)
                    }, 
                    _ => panic!("{}",e)                                         //what to do if error group isn't found
                )
            }
        };
...