递归宏的困难
Difficulty with Recursive Macro
我正在尝试使用宏删除此 Rust 代码中的代码重复:
enum AnyError { Error(Error), ParseIntError(ParseIntError), }
impl From<Error> for AnyError {
fn from(err: Error) -> AnyError { AnyError::Error(err) }
}
impl From<ParseIntError> for AnyError {
fn from(err: ParseIntError) -> AnyError { AnyError::ParseIntError(err) }
}
这是我正在尝试运行的宏代码,我相信它应该生成以上内容:
enum AnyError {
Error(Error),
ParseIntError(ParseIntError),
}
macro_rules! any_error {
($n: ident) => ();
($n: ident, $x:ident, $($y:ident),*) => {
impl From<$x> for $n {
fn from(err: $x) -> $n {
$n::$x(err)
}
}
any_error!($n, $($y),*);
};
}
any_error!(AnyError, Error, ParseIntError);
这是我从编译器得到的错误:
error: unexpected end of macro invocation
--> src/main.rs:17:28
|
9 | macro_rules! any_error {
| ---------------------- when calling this macro
...
17 | any_error!($n, $($y),*);
| ^ missing tokens in macro arguments
我已经尝试了很多不同的变体。如果我删除对 any_error!
的递归调用,那么它会成功生成 From
impls 之一,因此该部分看起来很好。有谁知道出了什么问题,或者编译器错误的实际含义?
问题是您的宏处理零个变体,两个或更多个变体,但当有正好一个:
any_error!(AnyError, Error); // None of the cases handle this!
一个可能的修复方法是将 ,
移动到 $y
匹配器中,这样在 exactly one 的情况下,宏不会期望尾随逗号:
macro_rules! any_error {
($n: ident) => ();
($n: ident, $x:ident $(, $y:ident)*) => {
impl From<$x> for $n {
fn from(err: $x) -> $n {
$n::$x(err)
}
}
any_error!($n $(, $y)*);
};
}
或者,您可以将 impl
放在 $()*
块中并完全跳过递归:
macro_rules! any_error {
($n: ident) => ();
($n: ident, $($x:ident),*) => {
$(
impl From<$x> for $n {
fn from(err: $x) -> $n {
$n::$x(err)
}
}
)*
};
}
我正在尝试使用宏删除此 Rust 代码中的代码重复:
enum AnyError { Error(Error), ParseIntError(ParseIntError), }
impl From<Error> for AnyError {
fn from(err: Error) -> AnyError { AnyError::Error(err) }
}
impl From<ParseIntError> for AnyError {
fn from(err: ParseIntError) -> AnyError { AnyError::ParseIntError(err) }
}
这是我正在尝试运行的宏代码,我相信它应该生成以上内容:
enum AnyError {
Error(Error),
ParseIntError(ParseIntError),
}
macro_rules! any_error {
($n: ident) => ();
($n: ident, $x:ident, $($y:ident),*) => {
impl From<$x> for $n {
fn from(err: $x) -> $n {
$n::$x(err)
}
}
any_error!($n, $($y),*);
};
}
any_error!(AnyError, Error, ParseIntError);
这是我从编译器得到的错误:
error: unexpected end of macro invocation
--> src/main.rs:17:28
|
9 | macro_rules! any_error {
| ---------------------- when calling this macro
...
17 | any_error!($n, $($y),*);
| ^ missing tokens in macro arguments
我已经尝试了很多不同的变体。如果我删除对 any_error!
的递归调用,那么它会成功生成 From
impls 之一,因此该部分看起来很好。有谁知道出了什么问题,或者编译器错误的实际含义?
问题是您的宏处理零个变体,两个或更多个变体,但当有正好一个:
any_error!(AnyError, Error); // None of the cases handle this!
一个可能的修复方法是将 ,
移动到 $y
匹配器中,这样在 exactly one 的情况下,宏不会期望尾随逗号:
macro_rules! any_error {
($n: ident) => ();
($n: ident, $x:ident $(, $y:ident)*) => {
impl From<$x> for $n {
fn from(err: $x) -> $n {
$n::$x(err)
}
}
any_error!($n $(, $y)*);
};
}
或者,您可以将 impl
放在 $()*
块中并完全跳过递归:
macro_rules! any_error {
($n: ident) => ();
($n: ident, $($x:ident),*) => {
$(
impl From<$x> for $n {
fn from(err: $x) -> $n {
$n::$x(err)
}
}
)*
};
}