问题描述
所以我有一个用于将Box<dyn error::Error>
与多种错误类型匹配的宏
#[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}
);
}
在我尝试添加火柴之前,它一直运行良好。当我尝试在模式中使用“ if”语句时,出现错误no rules expected the token 'if'
let _i = match example(2) {
Ok(i) => i,Err(e) => {
dynmatch!(e,type ExampleError1 {
arm ExampleError1::ThisError(2) => panic!("it was 2!"),_ => panic!("{}",e)
},type ExampleError2 {
arm ExampleError2::ThatError(8) => panic!("it was 8!"),arm ExampleError2::ThatError(9..=11) => 10,e)
},type std::io::Error {
arm i if i.kind() == std::io::ErrorKind::NotFound => panic!("not found"),//ERROR no rules expected the token `if`
_ => panic!("{}",e)
)
}
};
在我的模式匹配中有什么方法可以使用匹配保护而不会出现令牌错误?
解决方法
当然,即使我花了一个小时寻找解决方案,但在我发布此问题后,我却找到了答案。
正确的宏如下所示:
#[macro_export]
macro_rules! dynmatch {
($e:expr,$(type $ty:ty {$(arm $( $pattern:pat )|+ $( if $guard: expr )? => $result:expr),*,_ => $any:expr}),_ => $end:expr) => (
$(
if let Some(e) = $e.downcast_ref::<$ty>() {
match e {
$(
$( $pattern )|+ $( if $guard )? => {$result}
)*
_ => $any
}
} else
)*
{$end}
);
}
记入锈迹matches! source行244-251