macro_rules! declare_types {
($($token:ident -> $inner:ty, $to_string:expr,)*) => {
enum Value {
$($token($inner),)*
}
impl Display for Value {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
match self {
$(
Self::$token(inner)=>write!(fmt,"{}",$to_string)?,
)*
};
Ok(())
}
}
}
}
declare_types!(
String -> String, inner,
);
但是,该代码会导致编译器错误:
cannot find value `inner` in this scope
not found in this scope
当我将鼠标悬停在
inner
上时,IDE 会正确显示它:
此外,通过展开宏并将其粘贴回来,它可以正常工作而不会出现任何错误。
由于宏卫生,在宏内部创建的标识符(如
inner
中的Self::$token (inner)
)与在调用代码中创建的标识符(如inner
中的declare_types!(String -> String, inner);
)不同。如果您希望能够在显示的表达式中使用标识符,则需要将此标识符从调用者传递给宏:
macro_rules! declare_types {
($($token:ident -> $inner:ty, $id: ident, $to_string:expr,)*) => {
enum Value {
$($token($inner),)*
}
impl std::fmt::Display for Value {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
$(
Self::$token($id)=>write!(fmt,"{}",$to_string)?,
)*
};
Ok(())
}
}
}
}
declare_types!(
String -> String, inner, inner,
);