gpt4 book ai didi

rust - 匹配宏中的多种枚举类型

转载 作者:行者123 更新时间:2023-12-03 11:47:51 25 4
gpt4 key购买 nike

我有一个宏多数民众赞成用于匹配Box<dyn error::Error>与不同的枚举。现在我使用的是im版本,我需要针对每个错误类型在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)}
}
}
...
我的目标是做到这一点,这样我就可以将多种错误类型传递给它,并且它将为每种类型进行单独的匹配。唯一的问题是,要将类型从 Box<dyn error::Error>转换为其原始错误类型,我需要在其上调用 downcast_ref()。当传递的每个错误属于同一类型时,此方法工作正常,但是当我尝试为每个提供的 ARM 调用单独的匹配块时,它将引发错误 cannot infer type for type parameter 'T' declared on the associated function 'downcast_ref'
#[macro_export]
macro_rules! new_dyn_match {
($e:expr, $($pat:pat => $result:expr),*) => (
{
$(
if let Some(e) = $e.downcast_ref() { //cannot infer type for type parameter `T` declared on the associated function `downcast_ref`
if let $pat = e {$result}
}
)*
}
);
}

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

最佳答案

知道了!

#[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
)
}
};
...
归功于 this crate作为解决方案。
另外,如果有人对更好的解决方案有任何想法,请告诉我!

关于rust - 匹配宏中的多种枚举类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63866802/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com